学习笔记 -- Python协程_ gevent

  gevent 对协和的支持,本质上是greenlet在实现切换工作。工作流程如下:假如进行访问网络的IO操作时,出现阻塞,greenlet就显式切换到另一段没有被阻塞的代码段执行,直到原先的阻塞状态消失以后,再自动切换回原来的代码段继续处理。因此,greenlet是一种合理安排的串行方式。

  由于IO操作非常耗时,经常使程序处于等待状态,有了gevent为我们自动切换协程,就保证总有greenlet在运行,而不是等待IO,这就是协程一般比多线程效率高的原因。由于切换是在IO操作时自动完成,所有gevent需要修改Python自带的一些标准库,将一些常见的阻塞,如socket select等地方实现协程跳转,这一过程在启动时通过monkey patch完成。

 1 from gevent import monkey
 2 monkey.patch_all()
 3 import gevent
 4 import requests
 5 
 6 def run_task(url):
 7     print('Visit --> %s' % url)
 8     try:
 9         res = requests.get(url)
10         data = res.text
11         print('%d bytes received from %s.' % (len(data), url))
12     except Exception as e:
13         print(e)
14 
15 if __name__ == '__main__':
16     urls = ['https://github.com', 'https://www.python.org', 'http://www.cnblogs.com']
17     greenlets = [gevent.spawn(run_task, url) for url in urls]   # 生成协程
18     gevent.joinall(greenlets)  #  添加协程任务并且启动   所以有协程都是在同一个线程中完成的

还提供了Pool的支持

 1 from gevent import monkey; monkey.patch_all()
 2 import requests
 3 from gevent.pool import Pool
 4 
 5 def run_task(url):
 6     print('Visit --> %s' % url)
 7     try:
 8         res = requests.get(url)
 9         data = res.text
10         print('%d bytes received from %s.' % (len(data), url))
11     except Exception as e:
12         print(e)
13     return 'url: %s ---> finish' % url
14 
15 if __name__ == '__main__':
16     pool = Pool(2) # 创建池
17     urls = ['https://github.com', 'https://www.python.org', 'http://www.cnblogs.com']
18     results = pool.map(run_task, urls)  
19     print(results)

以上参考自《Python爬虫开发与项目实战》 机械工业出版社

原文地址:https://www.cnblogs.com/loayi/p/9008916.html