Unix IO 多路复用分析
学习《Unix 网络编程》,知道 select poll 是两种 IO 多路复用的解决方法,那么它们有什么区别。本文通过对 select poll 操作的 数据结构 进行分析,进一步了解它们到底做了什么。
本文使用 Linux 版本是 Ubuntu 18.04 。
select, poll
文中的示例从《UNIX 网络编程》源码的 tcpservselect01.c 和 tcpservpoll01.c 改编而来。可以在 Github 上下载。
select
echo-select.c
select 中 fd_set 的定义如下(可以使用 vscode 查看源码):
1 | /* The fd_set member is required to be an array of longs. */ |
使用一个由数组构成的结构体来表示一定长度的位(一般是 1024),这样一个 fd_set 代表一种类型,读/写/“异常”。
添加了一些输出代码,用来显示 select 操作的 fd_set 的数据变化。
- 使用
make echo-select
编译程序 - 使用
./echo-select
运行程序 - 在另一个终端使用
telnet 127.0.0.1 9999
进行连接 - 查看 echo-select 输出

如上图, listenfd 是 3 ,将 …0008 按二进制展开,即 …0000000000001000 ,表示 3 号文件描述符已经准备好。
poll
echo-poll.c
poll 中的 pollfd 定义:
1 | /* Data structure describing a polling request. */ |
使用一个结构体表示,一个文件描述符的相关信息。
- 使用
make echo-poll
编译程序 - 使用
./echo-poll
运行程序 - 使用
telnet 127.0.0.1 9999
进行连接 - 查看 echo-poll 输出

首先打印 pollfd 的宏定义。

listenfd 是 3 ,第一个 pollfd 写入 3 ,events 为 0001 ,即需要检查 POLLIN 。