CherryPy, Multiprocessing and Gevent monkey patching
我正在尝试结合使用cherrypy+多处理(启动工人的"进程")+gevent(从工人的"进程"中启动并行I/O greenlet)。这看起来最简单的方法是monkeypatch多处理,因为greenlets只能在主应用程序进程中操作。
但是,看起来猴子修补对多处理的某些部分有效,而对其他部分无效。这是我的Cherrypy服务器示例:
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | from gevent import monkey monkey.patch_all() import gevent import cherrypy import multiprocessing def launch_testfuncs(): jobs = [gevent.spawn(testfunc) for i in range(0, 12)] gevent.joinall(jobs, timeout=10) def testfunc(): print 'testing' class HelloWorld(object): def index(self): launch_testfuncs() return"Hello World!" index.exposed = True def index_proc(self): proc = multiprocessing.Process(target=launch_testfuncs) proc.start() proc.join() return"Hello World 2!" index_proc.exposed = True def index_pool(self): pool = multiprocessing.Pool(1) return"Hello World 3!" index_pool.exposed = True def index_namespace(self): manager = multiprocessing.Manager() anamespace = manager.Namespace() anamespace.val = 23 return"Hello World 4!" index_namespace.exposed = True cherrypy.quickstart(HelloWorld()) |
猴子修补后的工作如下:
index —直接从樱桃类中产卵。index_proc —使用multiprocessing.Process 启动一个新的进程,然后从该进程中产生绿叶
以下内容存在问题:
index_pool 发射multiprocessing.Pool 挂起,永不返回index_namespace —初始化multiprocessing.Manager 名称空间以管理池/工人集合中的共享内存—返回以下错误消息:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18[15/Nov/2012:17:19:31] HTTP Traceback (most recent call last):
File"/Library/Python/2.7/site-packages/cherrypy/_cprequest.py", line 656, in respond
response.body = self.handler()
File"/Library/Python/2.7/site-packages/cherrypy/lib/encoding.py", line 188, in __call__
self.body = self.oldhandler(*args, **kwargs)
File"/Library/Python/2.7/site-packages/cherrypy/_cpdispatch.py", line 34, in __call__
return self.callable(*self.args, **self.kwargs)
File"server.py", line 39, in index_namespace
anamespace = manager.Namespace()
File"/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/managers.py", line 667, in temp
token, exp = self._create(typeid, *args, **kwds)
File"/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/managers.py", line 565, in _create
conn = self._Client(self._address, authkey=self._authkey)
File"/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/connection.py", line 175, in Client
answer_challenge(c, authkey)
File"/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/connection.py", line 414, in answer_challenge
response = connection.recv_bytes(256) # reject large message
IOError: [Errno 35] Resource temporarily unavailable
我试图在Gevent文档中找到一些与此相关的文档,但找不到任何与此相关的文档。只是Gevent的猴子修补不完整吗?有没有其他人也有类似的问题,有没有解决的办法?
我也遇到过和你一样的问题。我的解决方案是,我刚刚使用multiprocessing.process()来生成固定数目的进程。最后加入所有人,等待完成。
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 27 28 29 30 31 32 33 34 35 36 | #!/usr/bin/env python # encoding: utf-8 from gevent import monkey monkey.patch_all() import gevent import multiprocessing as mp NUM = 10 def work(i): jobs = [gevent.spawn(func, i) for i in range(0, 12)] gevent.joinall(jobs) print"{} Done {}".format(mp.current_process().name, i) def func(x): print"Gevent: {}".format(x) def main(): processes = [mp.Process(name="Process-{}".format(i), target=work, args=(i,)) for i in xrange(NUM)] for process in processes: process.start() for process in processes: process.join() if __name__ == '__main__': main() |
输出
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 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | Gevent: 0 Gevent: 1 Gevent: 2 Gevent: 3 Gevent: 4 Gevent: 5 Gevent: 6 Gevent: 7 Gevent: 8 Gevent: 9 Gevent: 10 Gevent: 11 Process-0 Done 11 Gevent: 0 Gevent: 1 Gevent: 2 Gevent: 3 Gevent: 4 Gevent: 5 Gevent: 6 Gevent: 7 Gevent: 8 Gevent: 9 Gevent: 10 Gevent: 11 Process-1 Done 11 Gevent: 0 Gevent: 1 Gevent: 2 Gevent: 3 Gevent: 4 Gevent: 5 Gevent: 6 Gevent: 7 Gevent: 8 Gevent: 9 Gevent: 10 Gevent: 11 Process-2 Done 11 Gevent: 0 ... ... |
所以这是GEvent使用多处理的解决方案。
这个问题似乎是由于
您可以告诉
为此,请使用
这不是一个理想的解决方案,因为首先使用