当有数以万计的并发连接存在时,可能每一毫秒只有数百个活跃连接,当调用select返回活跃连接时,它需要将所有待监控连接传入,且需要在内核中遍历所有传递进来的fd,同时在高并发下会频繁调用。而epoll使用了三个方法来完成select要做的事情,这样就区分了频繁调用和不频繁调用的操作;比如对于创建epoll描述的epoll_create方法和用于添加/删除待监控连接的epoll_ctrl方法是不太频繁调用的,而返回活跃连接的epoll_wait方法时频繁调用的,对于epoll_wait方法,它不需要将所有待监控连接传入,也不需要遍历所有的fd,它在内部维护了一棵红黑树,该红黑树中存放了所有待监控连接,树中结点的增删是通过epoll_ctrl来完成,并且在相关的数据结构中维护了一个就绪链表,当指定的fd的I/O条件就绪时,通过回调函数把就绪的fd添加到就绪链表中,每次调用epoll_wait方法实际上只是检查并返回该链表。另外对于epoll_wait方法返回活跃连接有两种方式:边缘触发(ET)和水平触发(LT);边缘触发更倾向于精确的返回活跃连接,即连接只有从一个状态转换到另一个状态时才会被返回,这样epoll_wait调用次数就更少,在某些情况下连接就不会再不必要唤醒;而水平触发每次只要连接满足期待的状态就会被返回,比如如果监控到连接可写,如果应用进程未向连接写入任何数据,可能由于数据存放在磁盘中还未完全读取,那么对于ET而言是不会返回该连接的,而LT则会将该连接添加到就绪链表中。
Reactor模式将事件驱动逻辑和具体的业务逻辑分离,同时将不同类型请求之间用OO分离,在Reactor上提供注册/移除事件的方法供应用代码使用,而事件分发的方法,通常是循环的调用,Reactor通常是单线程的,好处是每个事件处理时不需要考虑....