poll(2)不会清空事件队列

时间:2010-06-11 08:01:59

标签: linux

我正在使用Linux作为我的编程平台。我正在使用poll(2)来了解我的设备是否正在触发事件。

poll的第一个电话是可以的;它阻止并等待事件发生。但是在第二个poll函数调用中,它将返回;但它抓住了这个事件。以下是我的代码。

ret = poll( fds, 1, 2000); //2 secs timeout

if( fds[0].revents & POLLIN && ret > 0)
{
   printf("event occur\n");
}

队列/缓冲区似乎不是空的。我只是假设。

您认为这是什么问题?

感谢。

5 个答案:

答案 0 :(得分:11)

显然,如果要轮询传入数据,则应使用可用数据(调用read()),否则它仍将存在,并且poll将立即返回。 POLLOUT实际上不需要对称操作,但通常需要尽快调用下一个write()。所以作为经验法则POLLIN - >读,POLLOUT - >写。

您还应该在再次调用poll之前重置pollfd结构。

fds[0].fd = sck;
fds[0].events = POLLIN;
fds[0].revents = 0;
ret = poll( fds, 1, 2000); //2 secs timeout

if( fds[0].revents & POLLIN && ret > 0)
{
   printf("event occur\n");
}

如果你不是每次都重置它,前一次调用的垃圾可以改变民意调查行为(嗯,不是真的,这只是一个可移植性问题)。

在生产代码中,您还必须检查返回值,因为轮询可能因预期事件(如信号)之外的其他原因而被中断。然后你通常想再次调用它而不是读取不可用的数据(提醒一下,轮询返回值是事件数,0超时,-1一些错误,其编号为errno)。

也可能发生提供给轮询的文件描述符的错误。它们不会使轮询返回错误,但会在该文件描述符的pollfd结构的revent字段中设置POLLERR,POLLHUP或POLLNVAL。如果设置了这些事件,则调用read将返回一些您可以检查的错误代码。

答案 1 :(得分:5)

如果您有POLLIN事件,这意味着“有数据可供阅读” - 您是否在再次read()之前调用了fd上的poll()函数?

答案 2 :(得分:4)

在读取文件描述符之前检查POLLHUPPOLLNVAL是一种很好的做法。但是,我认为read()只会失败,如果是这样的话,除非轮询一个预期会阻塞长时间段的文件描述符,比如调制解调器。在这种情况下,你会挂起(取决于你传递给open()的内容)。

你可能不是:

  • 在下一个poll()
  • 之前完全阅读事件FD
  • 阅读所有可用数据。

如果您在调用pollfd之前初始化了struct poll()数组,那么就不应该有任何“垃圾”。

尽管如此,在调用它之前还要检查并确保有一些值得打扰read()的事情可能是一个好主意。

答案 3 :(得分:4)

poll会为您提供一个事件,如果有数据/事件要读/错误/什​​么时候可以写。

如果您收到一条说“有数据要阅读”并且您没有阅读任何内容的活动 - 下次您致电poll并且您又收到其他活动时,仍会有“要阅读的数据”。

答案 4 :(得分:0)

  1. poll()返回0表示超时,如果发生错误则返回-1。另外,可以检查revents中是否有POLLERR

    if( poll_return == 0 || poll_return == -1 || ((int)recvpoll.revents & POLLERR) ) return 0 ;
    
  2. 如果要通过fork过程打开文件描述符,请关闭以前的文件描述符并打开新的文件描述符。