Python ZMQ和多处理导致ZMQ.error.ZMQError:系统调用中断

Python ZMQ和多处理导致ZMQ.error.ZMQError:系统调用中断,python,multiprocessing,zeromq,pyzmq,Python,Multiprocessing,Zeromq,Pyzmq,我有一个Python脚本,其中绑定了几个(例如5个)ZMQ接收器套接字,如下所示: receiver_1 = context.socket(zmq.PULL) receiver_1.bind("tcp://*:5555") ... receiver_5 = context.socket(zmq.PULL) receiver_5.bind("tcp://*:5559") receivers = [receiver_1, ..., receiver_5] 然后我启动一些Google计算引擎实例,

我有一个Python脚本,其中绑定了几个(例如5个)ZMQ接收器套接字,如下所示:

receiver_1 = context.socket(zmq.PULL)
receiver_1.bind("tcp://*:5555")
...
receiver_5 = context.socket(zmq.PULL)
receiver_5.bind("tcp://*:5559")

receivers = [receiver_1, ..., receiver_5]
然后我启动一些Google计算引擎实例,它们连接相应的发送方套接字

我希望并行地从这些套接字中提取数据,因此我尝试使用多处理池来实现这一点。代码如下所示:

def recv_result(i):
    result_str = receivers[i].recv()
    return cPickle.loads(result_str)

pool = multiprocessing.Pool()
while True:
    results = pool.map(recv_result, [i for i in range(len(receivers))])
    # break when all results have been received
    ...
Traceback (most recent call last):
  ...
  File ...
    results = pool.map(recv_result, [i for i in range(len(receivers))])
  File "/usr/lib/python2.7/multiprocessing/pool.py", line 227, in map
    return self.map_async(func, iterable, chunksize).get()
  File "/usr/lib/python2.7/multiprocessing/pool.py", line 528, in get
    raise self._value
zmq.error.ZMQError: Interrupted system call
运行脚本时出现的错误如下所示:

def recv_result(i):
    result_str = receivers[i].recv()
    return cPickle.loads(result_str)

pool = multiprocessing.Pool()
while True:
    results = pool.map(recv_result, [i for i in range(len(receivers))])
    # break when all results have been received
    ...
Traceback (most recent call last):
  ...
  File ...
    results = pool.map(recv_result, [i for i in range(len(receivers))])
  File "/usr/lib/python2.7/multiprocessing/pool.py", line 227, in map
    return self.map_async(func, iterable, chunksize).get()
  File "/usr/lib/python2.7/multiprocessing/pool.py", line 528, in get
    raise self._value
zmq.error.ZMQError: Interrupted system call
我也尝试过使用multiprocessing.Process实现相同的功能,但是我得到了基本相同的错误,尽管是以一种更混乱的方式

我试图做的是更有效地接收来自GCE实例的所有结果,因为我发现这是我脚本中的瓶颈(在我当前的工作实现中,我只有一个接收器套接字,它串行地接收来自所有GCE实例的结果)。如果有人能指出我当前代码中的错误,或者为实现我的目标提供更好的方法,我将不胜感激

几点提示:

  • 很好,您可以使用ZeroMQ-它可以在不编写太多代码的情况下为您做很多事情
  • 不要过度优化。通过ZeroMQ通信的多处理/线程化,您不会获得任何好处,它已经非常快,能够交换数量惊人的消息

  • 如果使用线程/多处理,永远不要共享zmq上下文,它必须是线程的私有上下文,否则它会中断。这可能是您出现异常的原因
  • 如果当前代码使用阻塞zeromq发送和接收,请将其更改为非阻塞。检查如何使用轮询

我的第一个想法是“为什么使用多线程”?我同意,这有点过早优化的味道。如果需要并行处理结果,请接收消息,然后将其传递给工作人员。串行接收消息应该可以。@Jason Nice ZeroMQ的想法是,它并行处理消息,而您不必关心。当然,一个线程中的Python代码将逐个串行地使用它们。另一方面,如果在多个进程或线程中需要更多的工作人员,zeromq可以很好地满足这一需求。我想强调的是,没有必要为邮件设置更多的通道来获得更高的吞吐量。感谢您的快速回复!在我自己的研究中,我在其他地方看到了很多类似的答案,似乎在许多GCE实例上运行脚本而不是在本地运行脚本时引入的大部分延迟都来自实际收集实例的结果(当计算结果不是瓶颈时,在本地运行大约快10倍). 我意识到我所做的可能不是解决此问题的最佳方法,您有任何进一步的建议吗?”“如果使用线程/多处理,永远不要共享zmq上下文,它必须是线程的私有上下文,否则它会断开。这可能是您的异常的原因。”“拯救生命!!:-)