epoll 原理
epoll_wait的工作流程:转:https://blog.csdn.net/eyucham/article/details/86502117
- epoll_wait调用ep_poll,当rdlist为空(无就绪fd)时挂起当前进程,直到rdlist不空时进程才被唤醒。
- 文件fd状态改变(buffer由不可读变为可读或由不可写变为可写),导致相应fd上的回调函数ep_poll_callback()被调用。
- ep_poll_callback将相应fd对应epitem加入rdlist,导致rdlist不空,进程被唤醒,epoll_wait得以继续执行。
- ep_events_transfer函数将rdlist中的epitem拷贝到txlist中,并将rdlist清空。
- ep_send_events函数(很关键),它扫描txlist中的每个epitem,调用其关联fd对用的poll方法。此时对poll的调用仅仅是取得fd上较新的events(防止之前events被更新),之后将取得的events和相应的fd发送到用户空间(封装在struct epoll_event,从epoll_wait返回)。
LT与ET模式 转:http://blog.chinaunix.net/uid-28541347-id-4273856.html
*epoll_wait返回的条件是rdlist不空,而使rdlist不空的途径有两个,分别对应图中的红线和蓝线。
*ET和LT模式下的epitem都可以通过红线方式加入rdlist从而唤醒epoll_wait,但LT模式下的epitem还可以通过蓝线方式重新加入rdlist唤醒epoll_wait。所以ET模式下,fd就绪(通过红线加入rdlist)只会被通知一次,而LT模式下只要满足相应读写条件就返回就绪(通过蓝线加入rdlist)。
*ET事件发生仅通知一次的原因是只被添加到rdlist中一次,而LT可以有多次添加的机会。