我正在尝试使用多进程池来运行一组进程,每个进程都将运行一个由greenlet组成的gevent池。原因是有很多网络活动,但也有很多CPU活动,所以为了最大化我的带宽和所有CPU核心,我需要多个进程和gevent的异步猴子补丁。我正在使用多进程的管理器来创建一个队列,进程将访问该队列以获取要处理的数据。
以下是代码的简化片段:
import multiprocessing
from gevent import monkey
monkey.patch_all(thread=False)
manager = multiprocessing.Manager()
q = manager.Queue()下面是它产生的异常:
Traceback (most recent call last):
File "multimonkeytest.py", line 7, in <module>
q = manager.Queue()
File "/usr/local/Cellar/python/2.7.2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/managers.py", line 667, in temp
token, exp = self._create(typeid, *args, **kwds)
File "/usr/local/Cellar/python/2.7.2/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 "/usr/local/Cellar/python/2.7.2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/connection.py", line 175, in Client
answer_challenge(c, authkey)
File "/usr/local/Cellar/python/2.7.2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/multiprocessing/connection.py", line 409, in answer_challenge
message = connection.recv_bytes(256) # reject large message
IOError: [Errno 35] Resource temporarily unavailable我相信这一定是由于普通套接字模块和gevent套接字模块之间的行为不同造成的。
如果我在子进程中进行monkeypatch,则队列创建成功,但是当子进程尝试从队列中获取()时,会发生非常类似的异常。由于在子进程中执行大量网络请求,套接字确实需要进行monkeypatched。
我的gevent版本,我相信它是最新的:
>>> gevent.version_info
(1, 0, 0, 'alpha', 3)有什么想法吗?
发布于 2013-02-07 02:50:09
使用monkey.patch_all(thread=False, socket=False)
我在类似的情况下遇到了同样的问题,并在gevent/monkey.py的patch_socket()函数下找到了第115行:_socket.socket = socket.socket。注释掉此行可以防止损坏。
这就是gevent用它自己的库替换stdlib socket库的地方。multiprocessing.connection广泛使用socket库,显然不能容忍这种变化。
具体地说,在导入的模块在不设置socket=False的情况下执行gevent.monkey.patch_all()调用的任何场景中都会出现这种情况。在我的例子中,这是grequests做的,我必须覆盖套接字模块的补丁来修复这个错误。
发布于 2013-02-12 04:06:18
不幸的是,在gevent上下文中应用多处理会引发问题。然而,您的理论基础是合理的(“大量的网络活动,但也有大量的CPU活动”)。如果你喜欢,可以看看http://gehrcke.de/gipc。这主要是为您的用例而设计的。使用gipc,您可以轻松地派生出几个完全支持gevent的子进程,并让它们相互协作和/或通过管道与父进程通信。
如果你有什么特别的问题,欢迎你来找我。
发布于 2013-10-20 16:22:04
如果您将使用原始队列,那么您的代码将正常工作,即使使用猴子修补的套接字。
import multiprocessing
from gevent import monkey
monkey.patch_all(thread=False)
q= multiprocessing.Queue()https://stackoverflow.com/questions/8678307
复制相似问题