协程可以理解为线程中的微线程,通过手动挂起函数的执行状态,在合适的时机再次激活继续运行,而不需要上下文切换。所以在python中使用协程会比线程性能更好。
上面有大牛分析的Tornado的线程实现,依赖与Tornado的IOLoop,所以不能单独拿出来使用。有几个需要理解的概念:
具体的实现过程不是很好描述,调度过程比较复杂,还是看看参考文章大牛的解析吧。
生成器实现的协程调度起来很麻烦,而且不是正在意义上的协程,只是实现的代码执行过程中的挂起,唤醒操作。而Greenlet这个Stackless的副产品则实现了真正的协程,在使用过程中通过switch来中断当前执行的函数,切换到另一个greenlet,在其它的geenlet 中调用switch会激活之前被挂起的协程。
Greenlet没有自己的调度过程,所以一般不会直接使用。以下参考文章是Greenlet get started的中文翻译。
http://www.importcjj.com/greenlet-qing-liang-ji-bing-fa-bian-cheng.html
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可以被定制来实现自己调度过程。
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
原文:https://www.cnblogs.com/ExMan/p/10426814.html