当我从套接字发送数据然后立即关闭它(不更改默认设置)时,会成功发送小数据大小,但不会发送大数据(> 2MB)。
以下是我如何设置接收器(最后阻塞recv()):
In [1]: import zmq
In [2]: ctx = zmq.Context()
In [3]: socket = ctx.socket(zmq.PULL)
In [4]: socket.connect("ipc://@foo")
In [5]: msg = socket.recv()
然后是发件人:
In [1]: import zmq
In [2]: ctx = zmq.Context()
In [3]: socket = ctx.socket(zmq.PUSH)
In [4]: socket.bind("ipc://@foo")
In [5]: arr = bytearray([1]*100)
In [6]: len(arr)
Out[6]: 100
In [7]: socket.send(arr); socket.close()
接收器获取的数据很好:
In [5]: msg = socket.recv()
In [6]: len(msg)
Out[6]: 100
但是如果我使用更大的消息,比如说arr = bytearray([1]*int(2e6))
,那么接收器会一直阻塞,等待数据。
更改LINGER设置似乎没有任何区别(我相信默认无限等待)。
在发送者和发送者之间添加睡眠(1)
socket.send(arr); time.sleep(1); socket.close()
解决了问题:接收方正确获取数据。
如果LINGER默认为-1,为什么没有睡眠就无法工作?在处理大量数据时,发送然后立即关闭套接字的正确方法是什么?
答案 0 :(得分:0)
它挂起,因为它没有收到任何消息(你太快关闭了推动器)。如果您打开一个新的PUSH
套接字并发送短消息,您会看到PULL
接收器运行良好并仍在侦听新消息。
在ZeroMQ FAQs中,您可以阅读:
如何刷新ZeroMQ套接字队列中的所有消息?
没有用于刷新特定消息或所有消息的明确命令 来自消息队列的消息。您可以将ZMQ_LINGER设置为0并关闭 套接字丢弃任何未发送的消息。
所以,基本上,如果你想确保发送消息,那么你需要在节点之间实现同步方法(即:使用REQ-REP
)。