博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

使用epoll&socket的总结

Posted on 2016-03-31 09:37  bw_0927  阅读(1507)  评论(0)    收藏  举报

http://www.cnblogs.com/zhiranok/archive/2011/12/25/epoll_socket.html

 

1. epoll 中使用et方式触发,只需EPOLL_CTL_ADD一次,把EPOLLIN  EPOLLOUT 事件全注册,每个socket只需创建add一次,其事件就会

     一直在epoll中,当然,socketclose 后应DEL掉。

2. ET触发方式是指当fd到状态发生变化时通知,如read buffer从无到有,write buffer从满到不满才会通知。

3. 若要将accept的文件描述符添加到epoll,那么同样需要将socket设置为nonblock,调用accept时要循环读,直到EWOULDBLOCK发生。

4. socket 无论是read/write事件,均需要循环读,知道EWOULDBLOCK发生。

5. accept 触发too many open file 时,accept到buffer已满,若close掉一些socket,仍然不能接受新连接,参见第2条,所以需要调用EPOLL_CTL_MOD重新触发accept事件,还一个简单方案,监听用到fd注册epoll是使用LT触发。

 

评论:

1。你的做法有问题,不能在开始的时候将EPOLLOUT注册进去,只有在决定发送数据的时候才注册,一旦发送完毕必须再取消该事件,否则你的epoll_wait将无法停住,因为在没有发送数据的时候,发送缓冲区始终处于可用状态。
 
 
2。
刚开始的时候我也纠结过此问题,但是使用ET模式这些问题则迎刃而解,ET模式下第一次注册会触发一次写(若write缓冲区空直接忽略)之后,除非write缓冲区状态发生变化,否则epoll不会通知,ET的语义是IO状态变化则通知。实际上大部分时间都不需要重复的epoll_add/del,原因有二,1.大部分时间write操作可以直接成功(write缓冲区只有连续发送大量数据时才阻塞),2.若此次write操作返回WOULDBLOCK(此时write缓冲区状态真正改变了,epoll_wait才会触发OUT事件),那么只许简单的将消息暂存缓冲区队列,等待OUT事件即可。