在调用getpid()时使用多处理循环的Python ZeroMQ

时间:2017-07-31 23:47:10

标签: python zeromq pyzmq

我对pyzmq有一种奇怪的行为。

我正在使用 multiprocessing 模块为每个进程创建一个带套接字( zmq.REP )的两个进程。我使用相同的上下文(zmq.Context())。

当我启动脚本时,我的CPU着火了,而我什么也没做。

所以,我查看了strace -p并注意到getpid()函数的无限调用。好吧,我甚至没有在代码中调用该函数。

下面的代码重现了这个问题:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import zmq
import multiprocessing

class Worker(multiprocessing.Process):

    def __init__(self, name, context):

        super(Worker, self).__init__()

        self._name = name
        self._ctx  = context

        self._sock = self._ctx.socket(zmq.REP)

    def run(self):

        while True:

            s = self._sock.recv()
            print s


def main():

    context  = zmq.Context()
    frontend = context.socket(zmq.ROUTER)
    backend  = context.socket(zmq.DEALER)

    frontend.bind("tcp://*:5555")
    backend.bind("ipc://backend.ipc")

    p = Worker('bar 1', context)
    p.daemon = True
    p.start()

    p = Worker('bar 2', context)
    p.daemon = True
    p.start()

    zmq.proxy(frontend, backend)


if __name__ == '__main__':
    main()

你有没有遇到过这个问题?

1 个答案:

答案 0 :(得分:0)

鉴于声明,上面的代码再现了问题,让我说明一下:

self._sock.recv( ) 的每次调用都应该产生错误状态 EFSM 或其他特定的ZeroMQ错误响应,因为 _sock 尚未进入正常状态(通过 .connect() .bind() ),因此它根本无法拨打.recv()

由于此类调用位于 while True: 内且_sock未进入阻塞状态(等待消息),因此循环以最快速度运行。< / p>

解决方案:

设置每个套接字,使其成为RTO状态 - 通过调用.connect( ... ).bind( ... ),无论如何,应该使用 {{1} } (使用Poller以便控制在阻塞状态下花费的时间,即使还没有消息也会返回主循环。