select,poll,epoll都是IO多路复用的机制。
select
- select每次调用都有拷贝列表数据到内核,每次都要做很多添加等待队列工作,唤醒时又要做很多移除工作。
- 进程唤醒后,还需要遍历一次才能知道哪些socket收到数据。
epoll
- 由于socket列表相对固定不变,epoll在内核维护了socket列表(红黑树)。epoll_create来新建,epoll_ctl来添加删除,epoll_wait来等待。
- socket就绪后不是直接通知进程,而是通过eventpoll中介。eventpoll维护了一个就绪列表。这样进程直接获取到就绪列表,不需要遍历所有。
epoll模式
- 水平触发(Level Triggered):只要句柄一直处于可用状态,就会一直通知用户。
- 边缘触发(Edge Triggered):句柄在发生读写事件时只会通知用户一次