epoll的再次认识

来源:互联网 发布:linux上装eclipse 编辑:程序博客网 时间:2024/06/10 01:45
使用mmap加速内核与用户空间的消息传递。
这 点实际上涉及到epoll的具体实现了。无论是select,poll还是epoll都需要内核把FD消息通知给用户空间,如何避免不必要的内存拷贝就很 重要,在这点上,epoll是通过内核于用户空间mmap同一块内存实现的。而如果你想我一样从2.5内核就关注epoll的话,一定不会忘记手工 mmap这一步的。


顺便看一下 EPOLLET 和 EPOLLLT
EPOLLLT 是默认行为,基本上就是说,只要一个文件描述符处于就绪状态,epoll 就会不停的通知你有事件发生。传统的 select/poll 都是这样的

EPOLLET 是新的方式,只在一个文件描述符新处于就绪的时候通知一次,之后不管数据有没有读完,都不会再通知,当然,有新数据到还是会通知的。所以,用 EPOLLET 的时候,一定要把文件描述符设置为 non-blocking,而且最好是一直读数据,读到返回 EAGAIN 才停下


EPOLLOUT事件:
EPOLLOUT事件只有在连接时触发一次,表示可写,其他时候想要触发,那要先准备好下面条件:
1.某次write,写满了发送缓冲区,返回错误码为EAGAIN。
2.对端读取了一些数据,又重新可写了,此时会触发EPOLLOUT。
简单地说:EPOLLOUT事件只有在不可写到可写的转变时刻,才会触发一次,所以叫边缘触发,这叫法没错的!
其实,如果真的想强制触发一次,也是有办法的,直接调用epoll_ctl重新设置一下event就可以了,event跟原来的设置一模一样都行(但必须包含EPOLLOUT),关键是重新设置,就会马上触发一次EPOLLOUT事件。
1. 缓冲区由满变空.
2.同时注册EPOLLIN | EPOLLOUT事件,也会触发一次EPOLLOUT事件
这个两个也会触发EPOLLOUT事件


EPOLLIN事件:
EPOLLIN事件则只有当对端有数据写入时才会触发,所以触发一次后需要不断读取所有数据直到读完EAGAIN为止。否则剩下的数据只有在下次对端有写入时才能一起取出来了。
现在明白为什么说epoll必须要求异步socket了吧?如果同步socket,而且要求读完所有数据,那么最终就会在堵死在阻塞里。

0 0