我有两个进程('发送方'和'接收方')需要通过瞬态单向FIFO通信管道进行通信,本地在一台机器上。这就是我想要发生的事情(使用更接近Unix域套接字的语言):
我的问题是:如何使用ZeroMQ实现这一点? “PUB / SUB”,“PUSH / PULL”?在ZMQ套接字中检测“数据结束”的机制是什么?是否可以允许上述前两项的两个排序:即发送方或接收方是否首先尝试连接?如果是这样,怎么样?
感谢。
答案 0 :(得分:5)
关于zeromq的事情:
您需要知道的一件事是,您不应该:当套接字连接时,它会创建一个管道(对等体尚不存在)。当套接字绑定时,它只在对等连接时创建管道。这些管道控制套接字的HWM行为。这意味着没有对等体的连接套接字和没有对等体的绑定套接字的行为是不同的。如果您尝试使用它发送消息,则没有对等体的绑定套接字将阻塞,而连接套接字将很乐意将消息排入内存中,直到对等体到达并开始使用消息。
基于这些要点,您要做的是:
这是Python中的一个工作示例,它使用IPC套接字(文件)进行通信,接收者在发送者之后的某个时间开始。
双方需要知道的共同信息:
import time
import zmq
# the file used for IPC communication
PIPE = '/tmp/fifo-pipe'
# command flags for our tiny message protocol
DONE = b'\x00'
MSG = b'\x01'
接收器(PULL)绑定,消耗直到DONE
def receiver():
ctx = zmq.Context()
s = ctx.socket(zmq.PULL)
s.bind("ipc://%s" % PIPE)
while True:
parts = s.recv_multipart()
cmd = parts[0]
if cmd == DONE:
print "[R] received DONE"
break
msg = parts[1]
# handle the message
print "[R] %.1f consuming %s" % (time.time() - t0, msg)
s.close()
ctx.term()
print "[R] done"
发送方(PUSH)连接并发送DONE信号完成
def sender():
ctx = zmq.Context()
s = ctx.socket(zmq.PUSH)
s.connect("ipc://%s" % PIPE)
for i in range(10):
msg = b'msg %i' % i
print "[S] %.1f sending %s" % (time.time() - t0, msg)
s.send_multipart([MSG, msg])
time.sleep(1)
print "[S] sending DONE"
s.send(DONE)
s.close()
ctx.term()
print "[S] done"
和一个演示脚本一起运行它们,发送者首先开始,接收者在发送者已经发送了几条消息之后开始:
from threading import Thread
# global t0, just for keeping times relative to start, rather than 1970
t0 = time.time()
# start the sender
s = Thread(target=sender)
s.start()
# start the receiver after a delay
time.sleep(5)
r = Thread(target=receiver)
r.start()
# wait for them both to finish
s.join()
r.join()
可以看到一起运行here。