协程gevent

协程gevent

1.进程,线程和协程

2.协程

3.用协程改生产者消费者模型

4.协程例子

5.利用协程爬取数据

 

1.进程,线程和协程

"""
进程是资源分配的最小单位
线程是程序调度的最下单位
协程是线程实现的具体方式


总结:
在进程一定的情况下,开辟多个线程,
在线程一定的情况下,创建多个协程,
以便提高更大的并行并发
"""

2.协程

from gevent import monkey;monkey.patch_all()
"""引入猴子补丁,可以实现所有的阻塞全部识别"""

import time
import gevent

def eat():
    print("eat1")
    time.sleep(3)
    print("eat2")
    
def play():
    print("play1")
    time.sleep(3)
    print("play2")


# 利用gevent.spawn创建协程对象g1
g1 = gevent.spawn(eat)
# 利用gevent.spawn创建协程对象g2
g2 = gevent.spawn(play)
# 如果不加join, 主线程直接结束任务,不会默认等待协程任务.

# 阻塞,必须等待g1任务完成之后在放行
g1.join()
# 阻塞,必须等待g2任务完成之后在放行
g2.join()

print(" 主线程执行结束 ... ")

 

3.用协程改生产者消费者模型

def producer():
    for i in range(1000):
        yield i

def consumer(gen):
    for i in range(10):
        print(  next(gen)  )
        
gen = producer()
consumer(gen)
print("<==========>")
consumer(gen)
print("<==========>")
consumer(gen)

 

4.协程例子

"""
# (1) spawn(函数,参数1,参数2,参数 .... ) 启动协程
# (2) join 阻塞,直到某个协程在任务执行完毕之后在放行
# (3) joinall 等待所有协程任务执行完毕之后放行;
      g1.join()  g2.join() <=> gevent.joinall( [g1,g2..] )
# (4) value 获取协程任务中的返回值 g1.value  g2.value
"""
from gevent import monkey ; monkey.patch_all()
import gevent
import time
import requests


def eat():
    print("eat1 开始吃 ... ")
    time.sleep(1)
    print("eat2 继续吃 ... ")
    return "吃完了"    
    
def play():
    print("play1 开始玩 ... ")
    time.sleep(1)
    print("play2 继续玩 ... ")
    return "玩完了"

# 创建协程对象g1
g1 = gevent.spawn(eat)
# 创建协程对象g2
g2 = gevent.spawn(play)
# 等待所有协程任务执行完毕之后放行
gevent.joinall( [g1,g2] )
print("主线程执行结束 ... ")
# 获取协程任务中的返回值
print(g1.value)
print(g2.value)

5.利用协程爬取数据

"""
HTTP 状态码
    200 ok
    400 bad request
    404 not found
"""

import requests
response = requests.get("http://www.baidu.com")
# print(response ,type(response) )

# 获取状态码
print(response.status_code)
# 获取网页中的字符编码
res = response.apparent_encoding
print(res) # utf-8
# 设置编码集,防止乱码
response.encoding = res
# 获取网页内容
res = response.text
print(res)


url_lst = [
    "http://www.baidu.com",
    "http://www.jd.com/",
    "http://www.taobao.com/",
    "http://www.amazon.cn/",
    "http://www.pinduoduo.com/",
    "http://www.4399.com/",
]


def get_url(url):
    response = requests.get(url)
    if response.status_code == 200:
        # print(response.text)
        pass
        
# (1) 正常爬取
"""
startime = time.time()
for i in url_lst:
    get_url(i)
endtime = time.time()
print(endtime-startime) # 12.648817539215088
"""
# (2) 用协程的方法爬取数据
lst = []

startime = time.time()
for i in url_lst:
    g = gevent.spawn(get_url , i)
    lst.append(g)
    
gevent.joinall( lst )
endtime = time.time()
print("主线程执行结束 ... 时间{}".format(endtime-startime)) # 1秒

 

回到顶部

posted @ 2020-11-14 14:49  流连、陌往返  阅读(34)  评论(0)    收藏  举报
点我跳转百度