gevent協程

Python經過yield提供了對協程的基本支持,可是不徹底。而第三方的gevent爲Python提供了比較完善的協程支持。python

gevent是第三方庫,經過greenlet實現協程,其基本思想是:git

當一個greenlet遇到IO操做時,好比訪問網絡,就自動切換到其餘的greenlet,等到IO操做完成,再在適當的時候切換回來繼續執行。因爲IO操做很是耗時,常常使程序處於等待狀態,有了gevent爲咱們自動切換協程,就保證總有greenlet在運行,而不是等待IO。github

因爲切換是在IO操做時自動完成,因此gevent須要修改Python自帶的一些標準庫,這一過程在啓動時經過monkey patch完成:網絡

 

先了解greenlet,這個庫用來學習的 功能不是不少。ide

 1 #!/usr/bin/env python
 2 # -*- coding:utf-8 -*-
 3  
 4  
 5 from greenlet import greenlet
 6  
 7  
 8 def test1():
 9     print 12
10     #切換到g2
11     gr2.switch()
12     print 34
13     #切換到g2繼續執行上次的任務
14     gr2.switch()
15  
16  
17 def test2():
18     print 56
19     gr1.switch()
20     print 78
21  
22 gr1 = greenlet(test1)
23 gr2 = greenlet(test2)
24 gr1.switch()
View Code

結果:學習

12
56
34
78fetch

經過switc方法能夠控制 協程何時切換,協程會記錄上次執行的點而後導入這個點繼續執行url

 

 

gevent庫方法(基於greenlet來作的):spa

 1 from gevent import monkey; monkey.patch_all()
 2 import gevent
 3 import urllib2
 4 
 5 def f(url):
 6     print('GET: %s' % url)
 7     resp = urllib2.urlopen(url)
 8     data = resp.read()
 9     print('%d bytes received from %s.' % (len(data), url))
10 
11 #這裏就不想greenlet須要手動切換,這裏是自動切換
12 gevent.joinall([
13         gevent.spawn(f, 'https://www.python.org/'),
14         gevent.spawn(f, 'https://www.yahoo.com/'),
15         gevent.spawn(f, 'https://github.com/'),
16 ])
View Code

 

 

openstack中用到的協程模塊eventlet3d

 1 import eventlet
 2 from eventlet.green import urllib2
 3 
 4 
 5 urls = [
 6     "http://www.baidu.com",
 7     "https://github.com/",
 8     "http://www.qq.com",
 9 ]
10 
11 
12 def fetch(url):
13     print(url)
14     return url,urllib2.urlopen(url).read()
15 
16 
17 pool = eventlet.GreenPool()
18 
19 
20 for url,body in pool.imap(fetch, urls):
21     print("go:%s === body-len:%d"%(url,len(body)))
View Code
相關文章
相關標籤/搜索