11

当使用 NOBLOCK 调用时,此代码将引发资源暂时不可用:

context = zmq.Context()
sender = context.socket(zmq.PUSH)
sender.bind('tcp://*:15556')
sender.send('KeEpAliv', zmq.NOBLOCK)  # this line will throw exception
#sender.send('KeEpAliv')  # this line will ok

阅读文档后,我没有发现任何提示。但是recv 的文档解释了这个标志。

4

1 回答 1

19

zmq.error.Again如果底层 C API返回EAGAIN.

现在,您应该遵循zmq_send文档,其中指出:

ZMQ_NOBLOCK
指定操作应该在非阻塞模式下执行。如果消息无法在套接字上排队,则 zmq_send() 函数将失败,并且将 errno 设置为 EAGAIN。

此外,在错误部分:

EAGAIN
请求了非阻塞模式,目前无法发送消息。

现在,为什么无法发送任何消息?在描述PUSH/PULL 套接字的页面上,我们可以阅读以下有关PUSH套接字的内容:

当对等点连接到它时,应创建此队列。如果此对等点断开连接,PUSH 套接字应销毁其队列并应丢弃其中包含的任何消息。

在任何对等方连接到您的套接字之前,没有地方可以发送消息,也没有队列。因此只有两件事是可能的:

  • 如果您send()以阻塞模式调用,它会阻塞直到对等方连接
  • 如果您send()在非阻塞模式下调用,它会zmq.error.Again提示您,该消息无法处理任何事情,您应该稍后再试。

请注意,如果每个已连接对等点的队列已满,您也可能会遇到此异常(PUSH套接字为每个已连接对等点创建一个单独的队列)。

于 2014-02-25T21:57:41.737 回答