转载:https://blog.csdn.net/wxy941011/article/details/80274233
epoll本质上是在内核注册了一个文件系统,如此,一颗红黑树,一张准备就绪句柄链表,少量的内核cache ,
就帮我们解决了大并发下的socket处理问题。
执行epoll_create时,创建了红黑树和就绪链表,
执行epoll_ctl时,如果增加socket句柄,则检查在红黑树中是否存在,存在立即返回,不存在则添加到树干上,然后向内核注册回调函数,用于当中断事件来临时向准备就绪链表中插入数据。
执行epoll_wait时立刻返回准备就绪链表里的数据即可。
LT, ET这件事怎么做到的呢?当一个socket句柄上有事件时,内核会把该句柄插入上面所说的准备就绪list链表,这时我们调用epoll_wait,会把准备就绪的socket拷贝到用户态内存,然后清空准备就绪list链表,最后,epoll_wait干了件事,就是检查这些socket,如果不是ET模式(就是LT模式的句柄了),并且这些socket上确实有未处理的事件时,又把该句柄放回到刚刚清空的准备就绪链表了。所以,非ET的句柄,只要它上面还有事件,epoll_wait每次都会返回这个句柄。( 从上面这段,可以看出,LT还有个回放的过程,低效了)