我在理解ZeroMQ高水位线(HWM)队列如何工作时遇到了一些困难。在
我做了两个脚本附在下面,它们复制了下面。在
我得到的结果是拉取器能够成功地接收(打印)所有消息。而且,推手似乎几乎立刻就完成了死刑。根据ZMQ official documentation我期望的是,由于到达HWM,在第二个send(...)
调用中被阻塞,因此推送器无法在拉器唤醒之前完成执行。{0.001>每一秒加一个相同的结果。在
所以,我的问题是:
send(...)
的第二次调用中没有阻塞?在脚本:
import zmq
context = zmq.Context()
push_socket = context.socket(zmq.PUSH)
push_socket.setsockopt(zmq.SNDHWM, 1)
push_socket.setsockopt(zmq.RCVHWM, 1)
push_socket.bind("tcp://127.0.0.1:5557")
print(push_socket.get_hwm()) # Prints 1
print('Sending all messages')
for i in range(2200):
push_socket.send(str(i).encode('ascii'))
print('Finished execution...')
为了重现我的测试用例,打开两个终端并首先启动拉具.py一次之后很快(4秒窗口)推进器.py在另一个。在
这里至少涉及4个缓冲区:zmq send buffer、OS write tcp buffer、OS read tcp buffer和zmq recv buffer。在
当消息成功写入OS tcp写入缓冲区时,zmq io线程将其标记为“已发送”。这些信息现在被认为是“在传输中”。在
然后,网络堆栈负责将尽可能多的数据传输到另一个进程的匹配OS recv缓冲区中, 最后,接收zmq io线程一次最多从这个缓冲区读取HWM消息到zmq recv队列。在
默认情况下,操作系统缓冲区通常在10-100kb左右,在ZMQ甚至注意到对方没有使用任何消息之前,这两个缓冲区都会被“正在传输”的消息填满。因为这些原因,你无法摆脱这些缓冲区。在
您的问题的解决方案可能涉及req/rep套接字和一个显式的应用程序级确认,即指南中的lazy pirate模式。在
相关问题 更多 >
编程相关推荐