针对 select 系统调用的三个不足,poll 解决的是第一个、最多 1024 个 FD 限制的问题。
其实现思路是:
1. 不再使用位图来传递事件和结果,而是使用 pollfd 。 结构体数组来传递。
2. 在内部实现时,以 poll_list 链表的形式来分批次保存 pollfd 。不像 select 那样一次申请完整的一大块内存。
3. 通过从进程的信号量里获取能打开的最大文件数量,解决 1024 个限制的问题。
0. 基本数据结构
// 源码位置:include/uapi/asm-generic/poll.h
struct pollfd {
int fd; // FD
short events; // 输入的敢兴趣事件
short revents; // 输出的结果
};
// 源码位置:fs/select.c
struct poll_list {
struct poll_list *next;
// entries 指向的数组里 pollfd 的数量
int len;
// 指向 pollfd 数组的指针
struct pollfd entries[0];
};
pollfd
结构体用来传递单个FD的输入事件、输出结果。
poll_list
是一个链表,其节点指向 pollfd 结构体的数组,这个数组要么是在栈上预分配、要么是按内存页分配(保持页对齐)。