python-3.x - ZeroMQ 卡在 python 多处理类/对象解决方案中

标签 python-3.x multiprocessing zeromq pyzmq

我正在尝试在 Python (pyzmq) 中使用 ZeroMQ 和多处理。作为一个最小(非)工作示例,我有一个服务器类和一个客户端类,它们都继承自 multiprocessing.Process .作为子进程的客户端应该向应该打印消息的服务器子进程发送一条消息:

#mpzmq_class.py

from multiprocessing import Process
import zmq


class Server(Process):
    def __init__(self):
        super(Server, self).__init__()
        self.ctx = zmq.Context()
        self.socket = self.ctx.socket(zmq.PULL)
        self.socket.connect("tcp://localhost:6068")

    def run(self):
        msg = self.socket.recv_string()
        print(msg)


class Client(Process):
    def __init__(self):
        super(Client, self).__init__()
        self.ctx = zmq.Context()
        self.socket = self.ctx.socket(zmq.PUSH)
        self.socket.bind("tcp://*:6068")

    def run(self):
        msg = "Hello World!"
        self.socket.send_string(msg)

if __name__ == "__main__":
    s = Server()
    c = Client()
    s.start()
    c.start()
    s.join()
    c.join()

现在,如果我运行它,服务器进程似乎在接收调用时挂起 msg = socket.receive_string() .在另一个(更复杂的)案例中,它甚至卡在 socket.connect("...") -陈述。

如果我重写脚本以使用函数而不是类/对象,它运行得很好:
# mpzmq_function.py

from multiprocessing import Process
import zmq


def server():
    ctx = zmq.Context()
    socket = ctx.socket(zmq.PULL)
    socket.connect("tcp://localhost:6068")
    msg = socket.recv_string()
    print(msg)


def client():
    ctx = zmq.Context()
    socket = ctx.socket(zmq.PUSH)
    socket.bind("tcp://*:6068")
    msg = "Hello World!"
    socket.send_string(msg)

if __name__ == "__main__":
    s = Process(target=server)
    c = Process(target=client)
    s.start()
    c.start()
    s.join()
    c.join()

输出:
paul@AP-X:~$ python3 mpzmq_function.py 
Hello World!

有人可以帮我解决这个问题吗?我想这是关于多处理的使用我不明白的事情。

谢谢!

最佳答案

我遇到了同样的问题。
我想问题是, run 方法无法访问上下文对象。
也许它与 C 实现以及进程没有共享内存的事实有关。
如果在 run 方法中实例化上下文,它就可以工作。

这是一个工作示例:

#mpzmq_class.py

from multiprocessing import Process
import zmq


class Base(Process):
    """
    Inherit from Process and
    holds the zmq address.
    """
    def __init__(self, address):
        super().__init__()
        self.address = address


class Server(Base):
    def run(self):
        ctx = zmq.Context()
        socket = ctx.socket(zmq.PULL)
        socket.connect(self.address)
        msg = socket.recv_string()
        print(msg)


class Client(Base):
    def run(self):
        ctx = zmq.Context()
        socket = ctx.socket(zmq.PUSH)
        socket.bind(self.address)
        msg = "Hello World!"
        socket.send_string(msg)


if __name__ == "__main__":
    server_addr = "tcp://127.0.1:6068"
    client_addr = "tcp://*:6068"
    s = Server(server_addr)
    c = Client(client_addr)
    s.start()
    c.start()
    s.join()
    c.join()

我添加了一个基类来证明您仍然可以从 run 方法访问普通的 Python 对象。如果将上下文对象放入 初始化 方法,行不通。

关于python-3.x - ZeroMQ 卡在 python 多处理类/对象解决方案中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44257579/

相关文章:

使用 ZeroMQ 时从线程调用 system()

c - 使用 ZeroMQ 在 C 中接收多部分消息

python - 如何在Python3中沿着第三维堆叠两个以上的numpy图像数组

python - "Pythonic"只要基于前一个元素的条件为真,就可以从可迭代对象中返回元素

python - 使用多处理模块进行集群计算

python 素数处理 : processing pool is slower?

c++ - 在 C++ 中解析时带有 protobuf 段错误的 zeromq

python-3.x - 无法获取页数。 poppler 是否已安装并位于 PATH 中?在苹果机上

python - 避免数据帧中的重复数据连接/合并/连接

python - 测试 python 多处理 : low speed because of overhead?