poll和事件异常

背景:今天看muduo网络库 发现一段代码:

 1   if ((revents_ & POLLHUP) && !(revents_ & POLLIN))
 2   {
 3     if (logHup_)
 4     {
 5       LOG_WARN << "fd = " << fd_ << " Channel::handle_event() POLLHUP";
 6     }
 7     if (closeCallback_) closeCallback_();
 8   }
 9 
10   if (revents_ & POLLNVAL)
11   {
12     LOG_WARN << "fd = " << fd_ << " Channel::handle_event() POLLNVAL";
13   }
14 
15   if (revents_ & (POLLERR | POLLNVAL))
16   {
17     if (errorCallback_) errorCallback_();
18   }
19   if (revents_ & (POLLIN | POLLPRI | POLLRDHUP))
20   {
21     if (readCallback_) readCallback_(receiveTime);
22   }
23   if (revents_ & POLLOUT)
24   {
25     if (writeCallback_) writeCallback_();
26   }

在muduo网络库中使用了两个IO复用的方法一个是POLL另一个是的EPOLL。

这连个的事件是一样的吗?

答案是 是一样的

引:《Linux 高性能服务器编程》 p152

epoll支持的事件类型和poll基本相同。表示epoll事件类型的宏是在poll对应的宏前面加上“E”。但是epoll有两个额外的事件类型  EPOLLET和EPOLLONESHOT。

在muduo网络库中有如下的用法:

1 static_assert(EPOLLIN == POLLIN,        "epoll uses same flag values as poll");
2 static_assert(EPOLLPRI == POLLPRI,      "epoll uses same flag values as poll");
3 static_assert(EPOLLOUT == POLLOUT,      "epoll uses same flag values as poll");
4 static_assert(EPOLLRDHUP == POLLRDHUP,  "epoll uses same flag values as poll");
5 static_assert(EPOLLERR == POLLERR,      "epoll uses same flag values as poll");
6 static_assert(EPOLLHUP == POLLHUP,      "epoll uses same flag values as poll");

这说明 epoll的事件和poll是重合的。

 

再来看看各个事件的含义及发生的条件:

 

 

这里面有一个POLLHUP发生挂起是什么意思。

这里找到一篇文档 http://www.greenend.org.uk/rjk/tech/poll.html

下面用我的蹩脚英语翻译一下:

标题:POLL() 和 EOF

 

提出问题:

poll是一个系统函数,它允许一个程序管理多个文件描述符,在这些文件描述符

发生可读或者可写事件的时候检测到这些事件。一个非常自然的问题是:当一个

文件描述符到达文件末尾时会发生什么? 是设置POLLIN事件还是设置POLLHUP

或者两者都设置。

 

相关文档说明:

在Single UNIX specification 里面写到,

 

POLL  : 除了高优先级的其它数据可以非阻塞的读取。 对于STREAMS,这个

标志位被设置在revents即使消息长度为0。

 

POLLHUP :这个设备已经断开连接,这个事件和POLLOUT是互斥的,当POLLHUP 

出现的时候这个流是不能写的。 然而这个事件和POLLIN,POLLRDNORM,POLLRDBAND和POLLPRI不是互斥的。这个事件仅仅在reventd中有有效在events中将被忽略。

 

对于 discannected 的定义不是很清晰, 到底是 end-of-file的条件还是像modem hanghuos

一样的东西()。

 

Stevens 在APUE中认为EOFs应该被POLLIN标记而不是POLLHUP。

 

具体实现

用pipe和socketpair实验结果如下:

 

 ”?“这个表格反映了我在做测试时不方便使用的组合。请随意发送更新(请参阅下面的测试程序)。当所描述的文件描述符位于文件末尾时,其他条目是在revents中设置的位。

 

https://stackoverflow.com/questions/24791625/how-to-handle-the-linux-socket-revents-pollerr-pollhup-and-pollnval/24791776

 

 

posted @ 2020-10-13 14:51  熊鑫xxx1x  阅读(962)  评论(0)    收藏  举报