我正在一个必须使用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函数。
希望你能帮助我
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的行为类似于可读的文件描述符。