协程之gevent
https://blog.csdn.net/weixin_45651336/article/details/109152460
pip install gevent
gevent在运行时的具体流程大概就是:
当一个greenlet遇到IO操作时,比如访问网络/睡眠等待,就自动切换到其他的greenlet,等到IO操作完成,再在适当的时候切换回来继续执行。由于IO操作非常耗时,经常使程序处于等待状态,有了gevent为我们自动切换协程,就保证总有greenlet在运行,而不是等待IO。同时也因为只有一个线程在执行,会极大的减少上下文切换的成本。
优势
- 代码中调用方便;
- 拥有的
monkey机制;
monkey机制
假设你不愿意修改原来已经写好的python代码,但是又想充分利用gevent机制,那么你就可以用monkey来做到这一点。你所要做的就是在文件开头打一个patch,那么它就会自动替换你原来的thread、socket、time、multiprocessing等代码,全部变成gevent框架。这一切都是由gevent自动完成的。注意这个patch是在所有module都import了之后再打,否则没有效果。
from gevent import monkey
monkey.patch_all()
#猴子补丁一般放在顶部,运行的时候修改原模块
import time
import gevent
def work1():
for i in range(5):
print("work1-----------")
time.sleep(1)
#默认不识别time.sleep()
#给gevent模块打补丁,。让识别time.sleep,在不修改程序原代码的情况下\
#为程序增加新功能
#打补丁方法是导入monkey模块,from gevent import monkey
#破解 monkey_patch_all()表示破解所有
#gevent.sleep(0.5)
def work2():
for i in range(5):
print("work2---->")
time.sleep(1)
#gevent.sleep(0.5)
if __name__ == '__main__':
g1=gevent.spawn(work1)
g2= gevent.spawn(work2)
g1.join()
g2.join()
输出
work1-----------
work2---->
work1-----------
work2---->
work1-----------
work2---->
work1-----------
work2---->
work1-----------
work2---->
创建协程对象
gevent.spawn()方法会创建一个新的greenlet协程对象,并运行
import gevent
def f1():
for i in range(5):
print('run func: f1, index: %s ' % i)
gevent.sleep(0)
def f2():
for i in range(5):
print('run func: f2, index: %s ' % i)
gevent.sleep(0)
t1 = gevent.spawn(f1)
t2 = gevent.spawn(f2)
gevent.joinall([t1, t2])
输出:
run func: f1, index: 0
run func: f2, index: 0
run func: f1, index: 1
run func: f2, index: 1
run func: f1, index: 2
run func: f2, index: 2
run func: f1, index: 3
run func: f2, index: 3
run func: f1, index: 4
run func: f2, index: 4
协程返回数据
# coding:utf8
import requests
import gevent
from gevent import monkey
monkey.patch_all() # 用于将标准库中大部分阻塞式调用修改为协作式运行
def fetch(url):
print("get: {}".format(url))
response = requests.get(url).content
return url, len(response)
if __name__ == "__main__":
g_list = list()
for url in ["https://stackoverflow.com/", "https://www.douban.com", "https://www.github.com"]:
g = gevent.spawn(fetch, url)
g_list.append(g)
gevent.joinall(g_list)
for g in g_list:
print(g.value)
浙公网安备 33010602011771号