一。定义
协程又称微线程,协程是一种用户态的轻量级的线程。
协程拥有自己的上下文和栈。协程调度切换Ⅹ,将寄存器上下文和栈保存到其它地方,再切换回来时,恢复到先前保存的寄存器上下文和栈。因此,协程能保留上一次调用的状态。
协程的好处:
无需线程上下文切换 的开销,即协程就是一个线程。
无需原子操作锁定及同步的开销
方便切换控制流,简化编程模型。
高开发,高拓展,低成,一个CPU可以支持上万的协程
二。用greenlet写协程
gr1.switch()
调用的方法
from greenlet import greenlet def test1(): print('12') gr2.switch() #相当于yield,会停下 print('34') gr2.switch() def test2(): print('56') gr1.switch() print('78')
gr1=greenlet(test1)
gr2=greenlet(test2)
gr1.switch()
gr2.switch()#同时生产的相当于一个生成器,switch就像next
三。Greent是一个第三库,可以实现并发同步或异步编程
gevent.spawn(foo)调用的方法
import gevent def foo(): print('runing foo ') gevent.sleep(1)#此处不能换成time.sleep是cup内部停止运行,#gevent.sleep是io阻塞的一种模拟 print('runing foo again') def bar(): print('runing bar ') gevent.sleep(2) print('runing bar again') gevent.joinall([ gevent.spawn(foo), gevent.spawn(bar) ])
四.协程在爬虫方面的应用
from gevent import monkey monkey.patch_all() #让系统识别io阻塞 import gevent from urllib.request import urlopen#用于爬虫的url import time def f(url): print('get:%s'%url) resp=urlopen(url)#打开该网址 data = resp.read() with open('python.html','wb') as f: f.write(data) gevent.joinall([ gevent.spawn(f,'http://www.python.org/'), gevent.spawn(f,'http://www.yahoo.org/'), ])