可以在传统和ZeroMQ套接字上使用.select()吗?

时间:2017-12-30 18:18:14

标签: python-3.x sockets zeromq distributed-system pyzmq

我有一个线程等待通过ZMQ和网络IO通过TCP发送信号输入(另一个用UDP做同样的事情)。

socket_tcp = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
socket_tcp.connect( ( self.config.tcp_ip, self.config.tcp_port ) )

while True:
    s_ready = zmq.select( [socket_zmq, socket_tcp], [], [] )[0]
        for sock in s_ready:
            # do stuff

但是,TCP套接字永远不会以可写方式返回(我确保它实际上使用Wireshark获取数据)。

文档说我可以通过

  

zmq.Socket或任何具有fileno()的Python对象               返回有效文件描述符的方法。

我认为socket.socket的后者是正确的。

与UDP相同。

我错过了什么吗?

我是否需要在单独的线程中处理ZMQ套接字并使用ctrl_rcv, ctrl_snd = multiprocessing.Pipe()传递其消息?

或者我可以在两个世界中使用select吗?正如我所期望的那样?

2 个答案:

答案 0 :(得分:0)

在使用asyncio后,我发现zmq.asyncio与我的用例完全正常。它使用zmq.Poller()(和zmq.select一样)。但出于某种原因,它只是有效......

所以我最终使用了ZMQSelector()以及一些额外的代码行:

import selectors
from zmq.asyncio import ZMQSelector

ctx = zmq.Context()
mixed_selector = ZMQSelector()
mixed_selector.register(sock_tcp, selectors.EVENT_READ)
mixed_selector.register(sock_zmq, selectors.EVENT_READ)

while True:
    fd_event_list = mixed_selector.select()
    for key, event in fd_event_list:
        sock = key.fileobj
        # do stuff

答案 1 :(得分:-1)

不要惊慌(还)

嗯,虽然最近的ZeroMQ API确实提供了 ZMQ_FD - 文件描述符代理来触摸ZeroMQ套接字实例,但这些实例只是一个提示a" 隐藏" -iceberg ,其行为方式与其他任何"常见" -socket抽象不同,如已发布{ {3}}

最佳
至少要警告 [here, so one ought better straight forget ZeroMQ to be "something-like-socket"] 部分中的主要概念差异

ZeroMQ框架工具的功能在于其简洁的设计,因此几乎可以肯定,如果仅使用并排的话,它将失去所有这些独特的优势。 (在任何 geeky 语法 - 构造函数技巧中),任何主要方式更简单(原语,如果有人希望的话)信令/消息传递设备。

如果到目前为止为实现ZeroMQ信令基础设施而付出了全部努力,那么不使用它将是一种无意义。

因此,相对于ZeroMQ更好地提供线程间消息传递,最好使用零拷贝智能 inproc:// 传输类,并避免任何特定于平台的开销 {{1此外,还会创建仅用于移动(...和复制)已知的数据(ZeroMQ可能会因零拷贝而享有超低延迟,如果适用)。