【问题标题】:zmq send with NOBLOCK raise Resource temporarily unavailablezmq send with NOBLOCK raise 资源暂时不可用
【发布时间】:2014-03-16 14:07:09
【问题描述】:

当使用 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

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

【问题讨论】:

    标签: sockets zeromq pyzmq


    【解决方案1】:

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

    现在,您应该关注zmq_send 文档,其中指出:

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

    另外,在错误部分:

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

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

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

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

    • 如果您在阻塞模式下调用 send(),它会阻塞直到对等方连接
    • 如果您在非阻塞模式下调用 send(),它会引发 zmq.error.Again 通知您,该消息无法处理,您应该稍后再试。

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

    【讨论】:

    • 谢谢,这给了我提示:send() in non-blocking mode, it raises zmq.error.Again.
    • 那么,我是否正确理解,当推送者可以在任何拉取者连接之前发送许多消息时,拥有这种“动态队列”的唯一方法是通过queue device?或“流光”设备?事实上,我已经为此尝试了队列设备(两侧都有 PUSH-PULL 套接字),它工作正常。刚刚阅读了 O'Reily 的书,我预计它会内置到套接字中。据我了解,只有 PUSH-PULL 套接字在没有人连接时不会排队?
    • 这是我的理解,虽然我已经很久没有接触过 ZMQ,但事情可能已经改变了。
    猜你喜欢
    • 2018-01-15
    • 1970-01-01
    • 2012-12-31
    • 2021-02-21
    • 2018-08-04
    • 2021-05-07
    • 2018-02-24
    • 2016-01-25
    • 2012-04-25
    相关资源
    最近更新 更多