学习嵌入式的第三十二天-数据结构-(2025.7.24)IO多路复用
IO多路复用定义
单线程或单进程同时监测若干个文件描述符(套接字)是否可以执行IO操作的能力。
作用
应用程序通常需要处理来自多条事件流中的事件,例如:
- 电脑需要同时处理键盘鼠标输入、中断信号等。
- Web服务器(如Nginx)需同时处理来自多个客户端的事件。
逻辑控制流在时间上的重叠称为并发。
并行指物理上同时执行多任务。
CPU单核同一时刻只能处理一件事,时分复用是常见解决方案:将CPU切割为时间片,不同事件流交替执行。线程或进程表示执行流,通过操作系统调度实现时分复用,使多个事件流看似并行。
并发处理的成本
- 线程/进程创建成本高。
- CPU切换线程/进程需上下文切换(页表、寄存器、缓存)。
- 多线程存在资源竞争问题。
IO多路复用提供单线程/进程中处理多事件流的方法,核心目标是用更少资源完成更多任务。
IO模型
- 阻塞IO:线程闲等待,主动让出CPU。
- 非阻塞IO:线程忙等待,反复检测IO状态(如
fcntl
设置O_NONBLOCK
)。 - 并发IO:多进程/线程处理,资源消耗较大。
- 多路IO:单进程/线程处理多个阻塞IO(如
select
、epoll
)。
IO多路复用是操作系统提供的IO事件检测机制。
select实现步骤
- 创建集合:
fd_set
定义变量。 - 添加关注的文件描述符:
FD_SET()
。 - 调用
select
等待IO事件(读/写)。 - 通过
FD_ISSET()
检查就绪的fd并操作。 - 清除标志位:
rd_set = temp_set
。
epoll实现步骤
- 创建集合:
epoll_create
。 - 添加关注的文件描述符:
epoll_ctl
。 - 调用
epoll_wait
等待IO事件,就绪的fd存入rev
集合。 - 在
rev
集合中直接操作就绪的fd。
select与epoll对比
特性 | select | epoll |
---|---|---|
最大fd数量 | 1024 | 通常支持>5000 |
检测方式 | 轮询所有fd | 事件驱动(主动上报) |
就绪fd查找 | 遍历原始集合(含未就绪fd) | 直接操作rev 集合(仅就绪fd) |