安装(以CentOS为例)
gevent依赖libevent和greenlet:
1.安装libevent
直接yum install libevent
然后配置python的安装
2.安装easy_install
(1)
1
|
wget -q http: //peak .telecommunity.com /dist/ez_setup .py
|
(2)使用
1
|
python ez_setup.py
|
(3)使用easy_install 查看命令是否可用,如果不可用可以讲路径加入到PATH中
3.安装greenlet
(1)
1
|
yum install python-devel
|
(2)
1
|
easy_install greenlet
|
4.安装gevent
1
|
pip install cython -e git: //github .com /surfly/gevent .git@1.0rc2 #egg=gevent
|
使用技巧
Gevent库性能很高,但一直以来我都纠结在python的GIL模型导致的线程不能抢占多核资源上面。
而启动多个python进程的这种利用多核的模式又需要增加前端负载均衡,比如lvs那些,有些麻烦。
multiprocessing模块和os.fork又会使得两个进程重复在事件核心注册accept事件,导致文件句柄重复的异常。
至于一个进程监听,多个进程处理的模式,监听的那个进程资源又不好分配——是独立分配一个核心还是不单独分配呢?如果单独分配,连接量小的时候就浪费了一个核心,如果不分配,连接量大的时候cpu又会频繁切换进程。
昨日才发现原来gevent是可以很轻松地将它的网络模型分布到多个进程并行处理的。
秘诀就在gevent.fork()。
以前想当然地认为gevent.fork只是greenlet.spawn的一个包装,原来不是这样。gevent.fork能替代os.fork,不仅会启动一个新的进程,而且能将它们底层的事件处理沟通起来,进行并行处理。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
import gevent
from gevent.server import StreamServer
def eat_cpu():
for i in xrange ( 10000 ): pass
def cb(socket, address):
eat_cpu()
socket.recv( 1024 )
socket.sendall( 'HTTP/1.1 200 OK\n\nHello World!!' )
socket.close()
server = StreamServer(('', 80 ), cb, backlog = 100000 )
server.pre_start()
gevent.fork()
server.start_accepting()
server._stopped_event.wait()
|
打上monkey.patch_os后,os.fork就可以被gevent.fork替代了,这样同时multiprocessing模块也可以像往常一样使用,并达到并行处理的效果了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
from gevent import monkey; monkey.patch_os()
from gevent.server import StreamServer
from multiprocessing import Process
def eat_cpu():
for i in xrange ( 10000 ): pass
def cb(socket, address):
eat_cpu()
socket.recv( 1024 )
socket.sendall( 'HTTP/1.1 200 OK\n\nHello World!!' )
socket.close()
server = StreamServer(('', 80 ), cb, backlog = 100000 )
server.pre_start()
def serve_forever():
server.start_accepting()
server._stopped_event.wait()
process_count = 4
for i in range (process_count - 1 ):
Process(target = serve_forever, args = tuple ()).start()
serve_forever()
|