我正在使用Linux作为我的编程平台。我正在使用poll(2)
来了解我的设备是否正在触发事件。
poll
的第一个电话是可以的;它阻止并等待事件发生。但是在第二个poll
函数调用中,它将返回;但它抓住了这个事件。以下是我的代码。
ret = poll( fds, 1, 2000); //2 secs timeout
if( fds[0].revents & POLLIN && ret > 0)
{
printf("event occur\n");
}
队列/缓冲区似乎不是空的。我只是假设。
您认为这是什么问题?
感谢。
答案 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)
在读取文件描述符之前检查POLLHUP
或POLLNVAL
是一种很好的做法。但是,我认为read()
只会失败,如果是这样的话,除非轮询一个预期会阻塞长时间段的文件描述符,比如调制解调器。在这种情况下,你会挂起(取决于你传递给open()
的内容)。
你可能不是:
poll()
或如果您在调用pollfd
之前初始化了struct poll()
数组,那么就不应该有任何“垃圾”。
尽管如此,在调用它之前还要检查并确保有一些值得打扰read()
的事情可能是一个好主意。
答案 3 :(得分:4)
poll
会为您提供一个事件,如果有数据/事件要读/错误/什么时候可以写。
如果您收到一条说“有数据要阅读”并且您没有阅读任何内容的活动 - 下次您致电poll
并且您又收到其他活动时,仍会有“要阅读的数据”。
答案 4 :(得分:0)
poll()
返回0表示超时,如果发生错误则返回-1。另外,可以检查revents
中是否有POLLERR
。
if( poll_return == 0 || poll_return == -1 || ((int)recvpoll.revents & POLLERR) ) return 0 ;
如果要通过fork过程打开文件描述符,请关闭以前的文件描述符并打开新的文件描述符。