【发布时间】:2020-12-04 20:58:16
【问题描述】:
我有 3 个进程,我们称它们为 host 和 worker1 和 worker2。我希望 worker1 和 worker2 能够通过 PUB/SUB 套接字直接相互通信(host 间歇性插入),所以我有以下设置:
# host
socket = ctx.Socket(zmq.PUB)
socket.bind('ipc:///tmp/comms')
# worker1
socket = ctx.Socket(zmq.PUB)
socket.connect('ipc:///tmp/comms')
socket.send(b'worker1')
# worker2
socket = ctx.Socket(zmq.SUB)
socket.connect('ipc:///tmp/comms')
socket.setsockopt(zmq.SUBSCRIBE, b'worker1')
socket.recv()
到目前为止,此设置不起作用。 worker1 发送正常,但 worker2 似乎从未收到该消息。但是,如果我现在将设置更改为:
# host
socket = ctx.Socket(zmq.PUB)
socket.connect('ipc:///tmp/comms')
# worker1
socket = ctx.Socket(zmq.PUB)
socket.connect('ipc:///tmp/comms')
socket.connect(b'worker1')
# worker2
socket = ctx.Socket(zmq.SUB)
socket.bind('ipc:///tmp/comms')
socket.setsockopt(zmq.SUBSCRIBE, b'worker1')
socket.recv()
它工作得很好。但是,如果我也绑定到host,它会再次停止工作。
这是为什么?如果我现在有workerN 也需要订阅worker1 会发生什么,我如何从所有进程中绑定?这些绑定/连接语义是什么? host 不是长寿进程,通过binding 做正确的事吗,如果是,为什么worker2 在connecting 时无法接收?
MWE:https://gist.github.com/ooblahman/f8f9724b9995b9646ebdb79d26afd68a
import zmq
import time
from multiprocessing import Process
addr = 'ipc:///tmp/test_zmq'
def worker1():
ctx = zmq.Context()
sock = ctx.socket(zmq.PUB)
sock.connect(addr)
while True:
sock.send(b'worker1')
print('worker1 sent')
time.sleep(1)
def worker2():
ctx = zmq.Context()
sock = ctx.socket(zmq.SUB)
sock.connect(addr) # Change this to bind
sock.setsockopt(zmq.SUBSCRIBE, b'worker1')
while True:
sock.recv()
print('worker2 heard')
def main():
ctx = zmq.Context()
sock = ctx.socket(zmq.PUB)
sock.bind(addr) # Change this to connect (or remove entirely)
p1 = Process(target=worker1)
p2 = Process(target=worker2)
p1.start()
p2.start()
p1.join()
if __name__ == '__main__':
main()
【问题讨论】:
标签: sockets zeromq distributed-computing pyzmq low-latency