【python】gevent学习
之前测试了stackless,感觉不太好. 不过python作为最火的脚本语言,还是吸引力难挡. python的协程方案,除了stackless,还有greenlet, 相应的事件框架也有gevent ,eventlet等. 先看gevent. 0.x版的gevent是基于libevent的,安装比较简单.还支持windows,先看这个. 1.x版的 gevent改成了libev的, 还需要安转cython,而且没有windows版的... 先来经典的击鼓传花 [python] view plain copy #!/bin/env python # -*- coding: utf-8 -*- #gevent版的击鼓传花(erlang和stackless的经典例子) #由n个节点组成一个环状网络,在上面传送共m个消息。 #将每个消息(共m个),逐个发送给1号节点。 #第1到n-1号节点在接收到消息后,都转发给下一号节点。 #第n号节点每次收到消息后,不再继续转发。 #当m个消息都从1号逐个到达第n号节点时,认为全部处理结束。 #每次执行时设定n=300,m=10000 import gevent from gevent.queue import Queue import sys if len(sys.argv) < 2: n=300 m=10000 else: n=int(sys.argv[1]) m=int(sys.argv[2]) print('start with n=%s,m=%s' % (n,m)) #创建队列 ch=range(1,n) for i in xrange(1,n): ch[i-1] = Queue() #结果队列 #result= Queue() #定义节点(协程) def node(i): while True: msg = ch[i-1].get() print('node %s got msg %s' % (i, msg)) if i==n-1: print ('msg %s reach last node %s' % (msg,i)); else: ch[i].put_nowait(msg) if msg>=m-1: print('final msg %s got,node %s quit' % (msg,i)); break #初始化消息 for k in xrange(1,m): print('send %s to node %s' % (k,1)) ch[0].put_nowait(k) #创建节点(协程) nodes=range(1,n) for j in xrange(1,n): nodes[j-1] = gevent.spawn(node, j) gevent.joinall(nodes) #[root@search2 test]# time ./tgering.py 3000 100 #real 0m0.803s #user 0m0.785s #sys 0m0.017s #[root@search2 test]# time ./tgering.py 10000 100 #real 0m2.499s #user 0m2.469s #sys 0m0.028s #[root@search2 test]# time ./tgering.py 100 10000 #real 0m2.201s #user 0m2.190s #sys 0m0.009s #[root@search2 test]# time ./tgering.py 300 10000 #real 0m7.082s #user 0m7.067s #sys 0m0.009s 这个性能还是很可观的. 公平起见,在相同环境测试了一下perl的coro性能(基于EV) 两者的差距在可以接受的范围. [python] view plain copy #[root@search2 perl]# time ./tring.pl 3000 100 #real 0m1.148s #user 0m1.128s #sys 0m0.016s #[root@search2 perl]# time ./tring.pl 10000 100 #real 0m3.865s #user 0m3.836s #sys 0m0.025s #[root@search2 perl]# time ./tring.pl 300 10000 #real 0m10.564s #user 0m10.529s #sys 0m0.024s #[root@search2 perl]#
参考资料:
http://blog.csdn.net/laputa73/article/details/12190317