运行 和 Python 多处理中的不同行为

Different behavior in run and start in Python multiprocessing

我正在尝试在 Python 程序中启动多个进程,使用 multiprocessing.Queue 在它们之间共享数据。

我的代码如下所示,TestClass是从zmq套接字接收数据包,并将它们送入队列的过程。还有一个进程(我从代码里拿出来的)一直在从队列中取消息。我还有一个脚本 运行 将消息发布到此 zmq 频道。

from multiprocessing import Process, Queue
import zmq
import time

class TestClass(Process):
    def __init__(self, queue):
        super(TestClass, self).__init__()

        # Setting up connections
        self.context = zmq.Context()
        self.socket = self.context.socket(zmq.SUB)
        self.socket.connect("tcp://192.168.0.6:8577")
        self.socket.setsockopt(zmq.SUBSCRIBE, b'')
        self.queue = queue

    def run(self):

        while True:
            msg = self.socket.recv()
            self.queue.put(msg)


queue = Queue()
c = TestClass(queue)
c.run()
# Do something else

如果我使用 c.run() 启动进程,它运行良好,但它没有作为进程启动,因为它阻止了以下语句。

然后我切换到c.start()开始进程,但是卡在socket.recv()行,收不到消息。有人可以解释一下并提出一个好的解决方案吗?谢谢

问题是您在父进程中创建了 zmq 套接字,然后试图在子进程中使用它。分叉过程中的某些东西正在破坏套接字,因此当您尝试使用它时它不起作用。您可以通过简单地在子项而不是父项中创建套接字来修复它。这没有负面影响,因为您一开始并没有尝试使用父级中的套接字。

from multiprocessing import Process, Queue
import zmq
import time

class TestClass(Process):
    def __init__(self, queue):
        super(TestClass, self).__init__()
        self.queue = queue

    def run(self):
        # Setting up connections
        self.context = zmq.Context()
        self.socket = self.context.socket(zmq.SUB)
        self.socket.connect("tcp://192.168.0.6:8577")
        self.socket.setsockopt(zmq.SUBSCRIBE, b'')

        while True:
            msg = self.socket.recv()
            self.queue.put(msg)


if __name__ == "__main__":
    queue = Queue()
    c = TestClass(queue)
    c.start()  # Don't use run()
    # Do something else