import gevent #自动IO切换 def foo(): print("running in foo") gevent.sleep(2) print('Explicit context switch to foo again') def bar(): print('Explict context to bar') gevent.sleep(2) print('Implicit context switch back to bar') def run3(): print("running func3") gevent.sleep(0) print("running func3 again") gevent.joinall([ gevent.spawn(foo), gevent.spawn(bar), gevent.spawn(run3) ])
实现一个异步IO并发的小爬虫:
from urllib import request import gevent from gevent import monkey monkey.patch_all() #urllib的IO阻塞gevent检测不到,所以即使异步程序执行起来也是串行 # 所以需要使用monkey.patch_all(),作用是把当前程序所有的IO操作做上标记,使程序能够异步切换 def f(url): print('GET:%s' % url) resp = request.urlopen(url) data = resp.read() f = open('/home/guqing/url.html','wb') f.write(data) f.close() print("%d bytes received from %s."%(len(data),url)) gevent.joinall([ gevent.spawn(f,'https://wwww.baidu.com'), gevent.spawn(f,'https://www.yahoo.com/'), gevent.spawn(f,'https:github.com/'), ])
使用yield实现简单协程:
import time def consumer(name): print("-------------->starting eating baozi....") while True: new_baozi = yield print("[%s] is eating baozi %s"%(name,new_baozi)) #time.sleep(1) def producer(): r1 = con.__next__() r2 = con2.__next__() n = 0 while n < 5: n += 1 con.send(n) con2.send(n) time.sleep(2) print(" 33[32;1m[producer] 33[0m is making baozi %s"%n) if __name__ == '__main__': con = consumer("c1") con2 = consumer("c2") p = producer()
greenlet手动切换协程:
__author__="Tim" from greenlet import greenlet def test1(): print(12) gr2.switch() print(34) gr2.switch() def test2(): print(56) gr1.switch() print(78) gr1.switch() gr1 = greenlet(test1) gr2 = greenlet(test2) gr1.switch()
gevent自动切换协程: