Py学习  »  分享发现

Gevent – 高性能的Python并发框架

Py站长 • 9 年前 • 7218 次点击  

Python通过yield提供了对协程的基本支持,但是不完全。而第三方的gevent为Python提供了比较完善的协程支持。

gevent是第三方库,通过greenlet实现协程,其基本思想是:

当一个greenlet遇到IO操作时,比如访问网络,就自动切换到其他的greenlet,等到IO操作完成,再在适当的时候切换回来继续执行。由于IO操作非常耗时,经常使程序处于等待状态,有了gevent为我们自动切换协程,就保证总有greenlet在运行,而不是等待IO。

由于切换是在IO操作时自动完成,所以gevent需要修改Python自带的一些标准库,这一过程在启动时通过monkey patch完成

Gevent是一个基于greenlet的Python的并发框架,以微线程greenlet为核心,使用了epoll事件监听机制以及诸多其他优化而变得高效。

于greenlet、eventlet相比,性能略低,但是它封装的API非常完善,最赞的是提供了一个monkey类,可以将现有基于Python线程直接转化为greenlet,相当于proxy了一下(打了patch)。

今天有空就迫不及待的试一下效果。

1、安装

Gevent依赖libevent和greenlet,需要分别安装。

#libevent 1.4.x
sudo apt-get install libevent-dev

#python_dev
sudo apt-get install python-dev

#easy_install
wget -q http://peak.telecommunity.com/dist/ez_setup.py
sudo python ./ez_setup.py

#greenlet
wget http://pypi.python.org/packages/source/g/greenlet/greenlet-0.3.1.tar.gz#md5=8d75d7f3f659e915e286e1b0fa0e1c4d
tar -xzvf greenlet-0.3.1.tar.gz
cd greenlet-0.3.1/
sudo python setup.py install

#gevent
wget http://pypi.python.org/packages/source/g/gevent/gevent-0.13.6.tar.gz#md5=7c836ce2315d44ba0af6134efbcd38c9
tar -xzvf gevent-0.13.6.tar.gz
cd gevent-0.13.6/
sudo python setup.py install

至此,安装完毕。

2、测试代码:XML-RPC

这里必须使用支持线程的XML-RPC,否则无法发挥gevent的优势!

传统版本: 需要说明的是,这个并很多资料描述的非单线程,而是一个select版本,所以某些时候比线程版本性能好。

from SocketServer import ThreadingMixIn
from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler

from SocketServer import TCPServer

TCPServer.request_queue_size = 10000

#Logic function
def add(a, b):
    return a + b

#Logic function 2
def gen(n):
    return '0' * n

#create server
server = SimpleXMLRPCServer(('', 8080), SimpleXMLRPCRequestHandler,False)
server.register_function(add, "add")
server.register_function(gen, "gen")
server.serve_forever()

线程版本

from SocketServer import ThreadingMixIn
from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler

#Threaded XML-RPC
class TXMLRPCServer(ThreadingMixIn, SimpleXMLRPCServer): pass

#Logic function
def add(a, b):
    return a + b

#Logic function 2
def gen(n):
    return "0" * n

#create server
server = TXMLRPCServer(('', 8080), SimpleXMLRPCRequestHandler)
server.register_function(add, "add")
server.register_function(gen, "gen")
server.serve_forever()

3、测试客户端

#Execute RPC
server = ServerProxy("http://localhost:8080")
#print server.add(3,5)
print server.gen(2048)

4、gevent的monkey包装后的XML-RPC

monkey是非入侵式的patch,只需要显示调用你需要patch的东西就行了,别看我用了三行,其实可以patch_all()的

from SocketServer import ThreadingMixIn
from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
from gevent import monkey

#Threaded XML-RPC && Monkey Patch
monkey.patch_socket() #Just 2 line!
monkey.patch_thread() #Just 3 line!
monkey.patch_select() #Just 3 line!
class TXMLRPCServer(ThreadingMixIn, SimpleXMLRPCServer): pass

#Logic function
def add(a, b):
    return a + b

#Logic function 2
def gen(n):
    return "0" * n

#create server
server = TXMLRPCServer(('', 8080), SimpleXMLRPCRequestHandler)
server.register_function(add, "add")
server.register_function(gen, "gen")
server.serve_forever()

其它资料:

官网: http://www.gevent.org/

关于gevent的一些理解(一) http://www.dongwm.com/archives/guanyugeventdeyixielijieyi-2/

gevent初步 http://www.isnowfy.com/introduction-to-gevent/

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/754
 
7218 次点击  
文章 [ 1 ]  |  最新文章 9 年前
爱情的枪
Reply   •   1 楼
爱情的枪    9 年前

顶下~