阻塞模式
- 发生I/O系统调用如果阻塞,进程会被挂起。
下面的各种模式都是为了解决阻塞模式带来的CPU消耗等问题
非阻塞模式
- 发生I/O系统调用如果阻塞,返回
-1并errno == EWOULDBLOCK.
根据Everything is a file的unix的设计哲学,通过 fcntl对fd操作,设置其为非阻塞模式。
I/O多路复用
- 具体的实现有(
select, epoll, kqueue, etc.)用一个线程对一系列的文件描述符遍历,通过文件操作方法poll来获得当前的状态,poll的实现是由相应的I/O驱动程序实现的。
![]()
如此就可以获得文件描述符的相应状态了。
epoll 效率高的原因
- 不需要每次将文件描述符从用户空间复制到内核空间,只需一次。
- 采用边缘触发模式,每当文件描述符状态发生改变,可以在
O(1)时间内唤醒相应的回调函数。
水平触发,边缘触发
select 只支持水平触发,epoll 支持水平触发和边缘触发。
水平触发(LT,Level Trigger):当文件描述符就绪时,会触发通知,如果用户程序没有一次性把数据读/写完,下次还会发出可读/可写信号进行通知。
边缘触发(ET,Edge Trigger):仅当描述符从未就绪变为就绪时,通知一次,之后不会再通知。
区别:边缘触发效率更高,减少了事件被重复触发的次数,函数不会返回大量用户程序可能不需要的文件描述符。

浙公网安备 33010602011771号