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中设置的位。

浙公网安备 33010602011771号