【问题标题】:Python ZMQ and multiprocessing causes zmq.error.ZMQError: Interrupted system callPython ZMQ 和多处理导致 zmq.error.ZMQError: Interrupted system call
【发布时间】:2014-06-25 08:52:41
【问题描述】:

我有一个 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 Compute Engine 实例,它们连接相应的发送方套接字。

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

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 实例的结果)。如果有人能指出我当前代码中的错误,或者任何关于实现目标的更好方法的建议,将不胜感激!

【问题讨论】:

    标签: python multiprocessing zeromq pyzmq


    【解决方案1】:

    一些提示:

    • 您使用 ZeroMQ 很好 - 它可以为您做很多事情而无需编写太多代码
    • 不要过度优化。您不会通过 ZeroMQ 通信的多处理/线程获得任何好处,它已经非常快并且能够交换数量惊人的消息
    • 如果使用线程/多处理,从不共享 zmq 上下文,它必须是线程私有的,否则会中断。这可能是您的异常的原因。
    • 如果当前代码使用阻塞 zeromq 发送和接收,请将其更改为非阻塞。查看如何使用轮询。

    【讨论】:

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