因爲python中的多線程比較特殊,因此協程的概念就變得尤其珍貴了,對於cpu密集型的操做,使用協程的效率無疑要好過多線程不少。由於協程的建立及其間切換的時間成本要低於線程不少。也由於這一點,不少人說,協程纔是python的將來,重要不重要!!!html
python中提供協程的模塊有兩個,greenlet和gevent。greenlet和gevent最大的區別在於greenlet須要你本身來處理線程切換, 就是說,你須要本身指定如今執行哪一個greenlet再執行哪一個greenlet。ps:這兩個包都不是python自帶的,因此須要手動安裝一下,pip就能夠輕鬆搞定!python
左側圖是greenlet的用法,我已經將執行順序標註出來了,從圖中咱們不難看出greenlet的執行順序是須要咱們手動控制的,如今再看看右側的圖是gevent的用法,就智能多了,它不須要咱們本身去支配,只要一個協程稍有空閒,gevent就幫你進行切換,已達到cpu的最大利用率。git
1 #!/usr/bin/env python 2 # -*- coding:utf-8 -*- 3 __author__ = 'Eva_J' 4 5 from greenlet import greenlet 6 7 def test1(): 8 print 12 9 gr2.switch() 10 print 34 11 gr2.switch() 12 13 14 def test2(): 15 print 56 16 gr1.switch() 17 print 78 18 19 gr1 = greenlet(test1) 20 gr2 = greenlet(test2) 21 gr1.switch()
1 import gevent 2 3 def foo(): 4 print('Running in foo') 5 gevent.sleep(0) 6 print('Explicit context switch to foo again') 7 8 def bar(): 9 print('Explicit context to bar') 10 gevent.sleep(0) 11 print('Implicit context switch back to bar') 12 13 gevent.joinall([ 14 gevent.spawn(foo), 15 gevent.spawn(bar), 16 ])
這裏再贈送一個gevent遇到IO操做自動切換的例子,這段代碼一看就是一副高大上的樣子,從老師那裏偷來的,嘻:github
1 #!/usr/bin/env python 2 #-*-coding:utf-8-*- 3 __author__ = 'Eva_J' 4 5 from gevent import monkey; monkey.patch_all() 6 import gevent 7 import urllib2 8 9 def f(url): 10 print('GET: %s' % url) 11 resp = urllib2.urlopen(url) 12 data = resp.read() 13 print('%d bytes received from %s.' % (len(data), url)) 14 15 gevent.joinall([ 16 gevent.spawn(f, 'https://www.python.org/'), 17 gevent.spawn(f, 'https://www.yahoo.com/'), 18 gevent.spawn(f, 'https://github.com/'), 19 ])
參考文獻:多線程
python的線程進程和協成:http://www.cnblogs.com/wupeiqi/articles/5040827.htmlide
greenlet背景介紹與實現機制:http://blog.jobbole.com/77240/url