zmq发送NOBLOCK引发资源暂时不可用

sch*_*acs 7 sockets zeromq pyzmq

使用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
Run Code Online (Sandbox Code Playgroud)

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

Cod*_*ers 15

zmq.error.Again如果底层C API返回,Python包装器会引发EAGAIN.

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

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

另外,在错误部分:

EAGAIN
请求了非阻止模式,此时无法发送消息.

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

当对等体连接到它时,应该创建此队列.如果此对等设备断开连接,则PUSH套接字应该销毁其队列,并且应该丢弃它包含的任何消息.

在任何对等体连接到套接字之前,无处发送消息,并且没有队列.因此,只有两件事是可能的:

  • 如果你send()以阻塞模式调用,它会阻塞直到对等连接
  • 如果您send()以非阻止模式呼叫,它会zmq.error.Again通知您,该消息无法执行任何操作,您应该稍后再试.

请注意,如果PUSH每个连接的对等方的队列都已满,您也可以获得此异常(套接字为每个连接的对等方创建一个单独的队列).