程序媛

python——协程

  由于python中的多线程比较特殊,所以协程的概念就变得尤为珍贵了,对于cpu密集型的操作,使用协程的效率无疑要好过多线程很多。因为协程的创建及其间切换的时间成本要低于线程很多。也因为这一点,很多人说,协程才是python的未来,重要不重要!!!

  python中提供协程的模块有两个,greenlet和gevent。greenlet和gevent最大的区别在于greenlet需要你自己来处理线程切换, 就是说,你需要自己指定现在执行哪个greenlet再执行哪个greenlet。ps:这两个包都不是python自带的,所以需要手动安装一下,pip就可以轻松搞定!

        

  左侧图是greenlet的用法,我已经将执行顺序标注出来了,从图中我们不难看出greenlet的执行顺序是需要我们手动控制的,现在再看看右侧的图是gevent的用法,就智能多了,它不需要我们自己去支配,只要一个协程稍有空闲,gevent就帮你进行切换,已达到cpu的最大利用率。

 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() 
greenlet Code
 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 example1 Code

  这里再赠送一个gevent遇到IO操作自动切换的例子,这段代码一看就是一副高大上的样子,从老师那里偷来的,嘻:

 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 ])
gevent example2 Code

参考文献:

    python的线程进程和协成:http://www.cnblogs.com/wupeiqi/articles/5040827.html

      greenlet背景介绍与实现机制:http://blog.jobbole.com/77240/

  

posted @ 2016-01-08 09:57  Eva_J  阅读(2973)  评论(1编辑  收藏  举报