当发件人关闭套接字时,为什么我的recv会挂起大邮件?

时间:2014-01-24 17:37:43

标签: python zeromq pyzmq

当我从套接字发送数据然后立即关闭它(不更改默认设置)时,会成功发送小数据大小,但不会发送大数据(> 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,为什么没有睡眠就无法工作?在处理大量数据时,发送然后立即关闭套接字的正确方法是什么?

1 个答案:

答案 0 :(得分:0)

它挂起,因为它没有收到任何消息(你太快关闭了推动器)。如果您打开一个新的PUSH套接字并发送短消息,您会看到PULL接收器运行良好并仍在侦听新消息。

ZeroMQ FAQs中,您可以阅读:

  

如何刷新ZeroMQ套接字队列中的所有消息?

     

没有用于刷新特定消息或所有消息的明确命令   来自消息队列的消息。您可以将ZMQ_LINGER设置为0并关闭   套接字丢弃任何未发送的消息。

所以,基本上,如果你想确保发送消息,那么你需要在节点之间实现同步方法(即:使用REQ-REP)。