Sockets zmq轮询器是如何工作的?

Sockets zmq轮询器是如何工作的?,sockets,zeromq,Sockets,Zeromq,我对poller在zmq中实际做了什么感到困惑。zguide对其进行了最低限度的介绍,并且仅将其描述为从多个套接字读取数据的一种方式。这对我来说不是一个令人满意的答案,因为它没有解释如何使用超时套接字。我知道push/pull模式的解释,但不知道req/rep模式,这是我想知道如何使用的 我想问的是:轮询器是如何工作的,它的功能如何应用于跟踪套接字及其请求?当您需要在同一线程中侦听不同的套接字时,请使用轮询器: ZMQ.Socket subscriber = ctx.socket(ZMQ.SUB

我对poller在zmq中实际做了什么感到困惑。zguide对其进行了最低限度的介绍,并且仅将其描述为从多个套接字读取数据的一种方式。这对我来说不是一个令人满意的答案,因为它没有解释如何使用超时套接字。我知道push/pull模式的解释,但不知道req/rep模式,这是我想知道如何使用的


我想问的是:轮询器是如何工作的,它的功能如何应用于跟踪套接字及其请求?

当您需要在同一线程中侦听不同的套接字时,请使用轮询器:

ZMQ.Socket subscriber = ctx.socket(ZMQ.SUB)
ZMQ.Socket puller = ctx.socket(ZMQ.PULL)
向轮询器注册套接字(
POLLIN
侦听传入消息)

轮询时,请使用循环:

while( notInterrupted()){
  poller.poll()

  //subscriber registered at index '0'
  if( poller.pollin(0)) 
     subscriber.recv(ZMQ.DONTWAIT)

  //puller registered at index '1'
  if( poller.pollin(1))
     puller.recv( ZMQ.DONTWAIT)
}
选择您要投票的方式

poller.poll()
阻塞,直到任一套接字上都有数据。
轮询器。轮询(1000)
块1s,然后超时

轮询器通知套接字上何时有可用的数据(消息);阅读它是你的工作

读取时,不要阻塞:
socket.recv(ZMQ.DONTWAIT)
。即使
poller.pollin(0)
检查是否有要读取的数据,也要避免轮询循环中的任何阻塞调用,否则,可能会由于套接字“卡住”而阻塞轮询器

因此,如果向
subscriber
发送两条单独的消息,您必须调用
subscriber.recv()
两次才能清除轮询器,否则,如果您调用
subscriber.recv()
一次,轮询器将不断告诉您还有另一条消息要读取。因此,本质上,轮询器跟踪消息的可用性和数量,而不是实际消息

您应该运行轮询示例并使用代码,这是最好的学习方法


这回答了你的问题吗?

在我列出的答案中

文件中的详细信息

此外,我还添加了一些重要的解释和东西,以消除新广告的混乱!如果你赶时间的话!您可能希望从以下内容开始:轮询器所做的事情和接收的情况以及关于接收的说明,以及结尾的一个套接字的情况部分!从重要注释部分开始!在那里我可以深入地了解事情!我仍然建议好好阅读参考文件中的细节!第一部分

文件编号及注释 侦听多个套接字和事件 zmq_poll()函数为应用程序提供一种机制,通过一组套接字以级别触发的方式多路传输输入/输出事件。items参数指向的数组的每个成员都是一个zmq_pollitem_t结构。nitems参数指定项目数组中的项目数。zmq_pollitem_t结构定义如下:

typedef结构
{
void//*插座/;
int//fd//;
短//事件//;
短//revents/;
}zmq_pollitem_t;
zmq插座或通过fd的标准插座 对于每个zmq_pollitem_t项,zmq_poll()应针对事件中指定的事件检查socket引用的ØMQ socket或文件描述符指定的标准socket如果套接字和fd都设置在单个zmq_pollitem_t中,则套接字引用的MQ套接字应优先,fd的值应忽略

大音符(相同上下文):

传递给zmq_poll()函数的所有ØMQ套接字必须共享相同的ØMQ上下文,并且必须属于调用zmq_poll()的线程

复仇者成员 对于每个zmq_pollitem_t项,zmq_poll()应首先清除revents成员,然后通过设置与revents成员中的事件条件对应的位来指示已发生的任何请求事件

成功完成后,zmq_poll()函数应返回在revents中发出事件信号的zmq_pollitem_t结构的数量,如果没有发出事件信号,则返回0

等待事件和阻塞 如果在任何zmq_pollitem
项目上未发生任何请求的事件zmq_poll()应在任何请求的项目上等待超时微秒事件发生。如果超时值为0zmq_poll()应立即返回。如果超时值为-1,则zmq\u poll()将无限期地阻止,直到至少一个zmq\u poll项上发生请求的事件为止超时的分辨率为1毫秒

  • 0=>不等待

  • -1=>块

  • +val=>阻塞并等待超时量

事件 zmq_pollitem_t的事件和revents成员是通过或组合以下事件标志构建的位掩码:

ZMQ_POLLIN 对于ØMQ套接字,至少可以从套接字接收一条消息而不阻塞。对于标准套接字,这相当于poll()系统调用的POLLIN标志,通常意味着至少可以从fd读取一个字节的数据而不阻塞

ZMQ_轮询器 对于ØMQ套接字,至少可以向套接字发送一条消息而不阻塞。对于标准套接字,这相当于poll()系统调用的POLLOUT标志,通常意味着至少可以将一个字节的数据写入fd而不阻塞

ZMQ_POLLERR 对于标准套接字,该标志通过zmq_poll()传递给底层poll()系统调用,通常意味着fd指定的套接字上存在某种错误条件。对于ØMQ套接字,如果在事件中设置该标志,则该标志无效,并且zmq_poll()永远不会在revents中返回该标志

注:

zmq_poll()函数可以由emu或emu实现
while( notInterrupted()){
  poller.poll()

  //subscriber registered at index '0'
  if( poller.pollin(0)) 
     subscriber.recv(ZMQ.DONTWAIT)

  //puller registered at index '1'
  if( poller.pollin(1))
     puller.recv( ZMQ.DONTWAIT)
}
while(true) {
    socket1.recv() // this will block

    socket2.recv() // this will have to wait till the first recieve! Even if messages come in in it's queue
While(true) {
    zmq_poll() // block till one of the socket events happen! If the event was POLLIN!
            // If any socket get a message to it's queue
            // This will unblock
    // then we check which type and which socket was
    if (condition socket 1) {
        // treat socket 1 request
    }

    if (condition socket 2) {
        // treat socket 2 request
    }
 
    // ...
}