1. 程式人生 > >Python協程 Gevent Eventlet Greenlet

Python協程 Gevent Eventlet Greenlet

started 切換 需要 htm turn 一次 csdn nth tar

https://zh.wikipedia.org/zh-cn/%E5%8D%8F%E7%A8%8B

協程可以理解為線程中的微線程,通過手動掛起函數的執行狀態,在合適的時機再次激活繼續運行,而不需要上下文切換。所以在python中使用協程會比線程性能更好。

Tornado協程

http://blog.csdn.net/wyx819/article/details/45420017

上面有大牛分析的Tornado的線程實現,依賴與Tornado的IOLoop,所以不能單獨拿出來使用。有幾個需要理解的概念:

  1. Future對象 用來保存異步獲取到的結果,並在set_reslut的時候調用callback方法,把對應的callback方法放到ioloop的callback列表中等待下一次ioloop循環再執行
  2. 裝飾器coroutine 在這個裝飾器中實現了協程的調度,通過不斷的調用next函數來不斷獲取Future對象,然後每次拿到Future對象在add_callback到ioloop上,等到Future被set_reslut後再次next,直到生成器中拋出Return的異常。

具體的實現過程不是很好描述,調度過程比較復雜,還是看看參考文章大牛的解析吧。

Greenlet

生成器實現的協程調度起來很麻煩,而且不是正在意義上的協程,只是實現的代碼執行過程中的掛起,喚醒操作。而Greenlet這個Stackless的副產品則實現了真正的協程,在使用過程中通過switch來中斷當前執行的函數,切換到另一個greenlet,在其它的geenlet 中調用switch會激活之前被掛起的協程。

Greenlet沒有自己的調度過程,所以一般不會直接使用。以下參考文章是Greenlet get started的中文翻譯。

http://www.importcjj.com/greenlet-qing-liang-ji-bing-fa-bian-cheng.html

Eventlet

http://blog.csdn.net/gaoxingnengjisuan/article/details/12913275
http://blog.csdn.net/gaoxingnengjisuan/article/details/12914831

Eventlet在Greenlet的基礎上實現了自己的GreenThread,實際上就是greenlet類的擴展封裝,而與Greenlet的不同是,Eventlet實現了自己調度器稱為Hub,Hub類似於Tornado的IOLoop,是單實例的。在Hub中有一個event loop,根據不同的事件來切換到對應的GreenThread。

同時Eventlet還實現了一系列的補丁來使Python標準庫中的socket等等module來支持GreenThread的切換。Eventlet的Hub可以被定制來實現自己調度過程。

Gevent

http://xlambda.com/gevent-tutorial/
http://www.open-open.com/lib/view/open1409705174822.html

Gevent的2架馬車,libev與Greenlet。不同於Eventlet的用python實現的hub調度,Gevent通過Cython調用libev來實現一個高效的event loop調度循環。同時類似於Event,Gevent也有自己的monkey_patch,在打了補丁後,完全可以使用python線程的方式來無感知的使用協程,減少了開發成本。

在Python的世界裏由於GIL的存在,線程一直都不是很好用,所以就有了各種協程的hack。Gevnet是當前使用起來最方便的協程了,但是由於依賴於libev所以不能在pypy上跑,如果需要在pypy上使用協程,Eventlet是最好的選擇。

Python協程 Gevent Eventlet Greenlet