select(2)
- 为什么需要select
- select参数
- select流程
为什么需要select?
每个I/O操作(如网络请求)需要阻塞一个线程,当并发量高时(例如数万连接),线程数量爆炸式增长。通过操作系统内核提供的机制(如select/poll/epoll),单线程可以监听多个I/O描述符的状态变化,仅当某个I/O操作真正就绪时(如数据到达、缓冲区可写),才触发用户程序处理,避免无效等待。
幸运的是 现代OS大 部分支持IO多路复用
select
select流程
- 初始化文件描述符集合
- 使用
FD_ZERO
、FD_SET
将需要监听的 fd 添加到readfds
/writefds
/exceptfds
。 - 计算机硬件条件不同 set分为
read_set
write_set
except_set
- 使用
- 调用
select
- 阻塞等待,直到至少一个 fd 就绪或超时。
- 检查就绪的 fd
- 遍历所有被监听的 fd,通过
FD_ISSET
判断哪些 fd 触发了事件。 - 一个进程管理多个资源 当进程阻塞时 内核轮询 arguments是非const的 要放在loop里面
- 遍历所有被监听的 fd,通过
- 处理事件
- 对就绪的 fd 进行读/写/异常处理。
select 是 I/O 多路复用的一种经典实现,允许程序同时监视多个文件描述符(如套接字),并在其中任意一个就绪(可读、可写或异常)时触发操作。虽然它已被 epoll(Linux)和 kqueue(BSD)等更高效的机制取代,但其跨平台特性使其在特定场景下仍有价值。
核心特性
- 跨平台支持
- 几乎所有操作系统(Linux、Windows、macOS 等)都支持
select
。
- 几乎所有操作系统(Linux、Windows、macOS 等)都支持
- 同步阻塞模型
- 调用
select
时线程会阻塞,直到有文件描述符就绪或超时。
- 调用
- 水平触发(LT)
- 只要文件描述符处于就绪状态,每次调用
select
都会触发通知。
- 只要文件描述符处于就绪状态,每次调用