在zmq中使用计时器

问题描述 投票:0回答:1

我正在一个必须使用zmq_poll的项目中工作。但是我不完全了解它的作用。

我看过这个例子:

zmq_pollitem_t items [2];
/* First item refers to ØMQ socket 'socket' */
items[0].socket = socket;
items[0].events = ZMQ_POLLIN;
/* Second item refers to standard socket 'fd' */
items[1].socket = NULL;
items[1].fd = fd;
items[1].events = ZMQ_POLLIN;
/* Poll for events indefinitely */
int rc = zmq_poll (items, 2, -1);
assert (rc >= 0); /* Returned events will be stored in items[].revents */

在他们的网站上:http://api.zeromq.org/2-1:zmq-poll

所以我也尝试实现它:

zmq_pollitem_t timer_open(void){

  zmq_pollitem_t items[1];


    if( items[0].socket  == nullptr ){
         printf("error socket %s: %s\n", zmq_strerror(zmq_errno()));
         return;        
    }
else{
    items[0].socket = gsock; 
} 


items[0].fd = -1;   
items[0].events = ZMQ_POLLIN;  


 // get a timer
items[0].fd  = timerfd_create( CLOCK_REALTIME, 0 );
    if( items[0].fd  == -1 )
    {
    printf("timerfd_create() failed: errno=%d\n", errno);
            items[0].socket  = nullptr;

            return;
    }

int rc = zmq_poll(items,1,-1);

if(rc == -1){
    printf("error poll %s: %s\n", zmq_strerror(zmq_errno()));
    return;
} 
else
     return items[0];
}

我对这个主题非常陌生,我必须修改一个旧的现有项目,并用zmq之一替换功能。在其他网站上,我看到了一些示例,其中它们使用两个项目,并且zmq_poll函数无休止地循环。我已经阅读了文档,但仍然无法正确理解其工作原理。这些是我实现的其他两个功能。我不知道这是否是实现它的正确方法:

   void timer_set(zmq_pollitem_t items[] , long msec, ipc_timer_mode_t mode ) {


    struct itimerspec t;

    ...

    timerfd_settime( items[0].fd , 0, &t, NULL );

}


void timer_close(zmq_pollitem_t items[]){

if( items[0].fd != -1 )
       close(items[0].fd);

items[0].socket = nullptr; 

}

由于使用计时器,因此不确定是否需要zmq_poll函数。

希望你能帮助我

c++ c sockets timer zeromq
1个回答
0
投票

zmq_poll的作用类似于select,但它允许一些其他内容。例如,您可以在常规同步文件描述符和特殊的异步套接字之间进行选择。

根据您的情况,您可以尝试使用计时器fd,但是需要进行一些小的更改。

首先,您必须考虑如何调用这些计时器。我认为用例是您要创建多个计时器并等待它们。这通常是您当前代码中的功能,该功能可能正在使用计时器循环(使用select()或它们可能正在执行的其他操作)。就像这样:

void some_function() {
   // We want to wait on two timers
   zmq_pollitem items[2];

   // Setup first timer
   ipc_timer_open(&item[0]);
   ipc_timer_set(&item[0], 1000, IPC_TIMER_ONE_REPEAT);
   // Setup second timer
   ipc_timer_open(&item[1]);
   ipc_timer_set(&item[1], 5000, IPC_TIMER_ONE_SHOT);

   // Now wait for the timers in a loop
   while (1) {
      int rc = zmq_poll (items, 2, -1);
      assert (rc >= 0); /* Returned events will be stored in items[].revents */
   }
}

现在,您需要修复ipc_timer_open。这将非常简单-只需创建计时器fd。

// Takes a pointer to pre-allocated zmq_pollitem_t and returns 0 for success, -1 for error
int ipc_timer_open(zmq_pollitem_t *items){
    items[0].socket = NULL; 
    items[0].events = ZMQ_POLLIN;  
    // get a timer
    items[0].fd  = timerfd_create( CLOCK_REALTIME, 0 );
    if( items[0].fd  == -1 )
    {
        printf("timerfd_create() failed: errno=%d\n", errno);
        return -1; // error
    }
    return 0;
}

编辑:已添加为对评论的回复,因为这很长:从文档中:If both socket and fd are set in a single zmq_pollitem_t, the ØMQ socket referenced by socket shall take precedence and the value of fd shall be ignored.

因此,如果要传递fd,则必须将套接字设置为NULL。我什至不清楚gsock的来源。这在文档中吗?我找不到。

它何时会退出while(1)循环?

这是应用程序逻辑,您必须根据需要进行编码。 zmq_poll每次计时器命中时都会不断返回。在此示例中,由于第一个计时器(重复)不断触发,因此zmq_poll每秒钟返回一次。但是在5秒后,由于第二个计时器(一次射击),它也会返回。由您决定何时退出循环。您是否要无限进行?您是否需要检查其他条件才能退出循环?您要说100次然后返回吗?您可以在此代码之上编写所需的任何逻辑。

以及返回什么样的事件

ZMQ_POLLIN,因为计时器fds的行为类似于可读的文件描述符。

© www.soinside.com 2019 - 2024. All rights reserved.