上文说到的实现IO复用的函数中的select,本文接着介绍第二种poll。
poll
Poll相对于select来说突破了监听的文件描述符上限1024,最大文件描述符是系统所能允许的最大值,可以通过查看proc/sys/fs/file-max文件查看,这个值也可以改(通过limits.conf)。另一方面是实现了监听和就绪事件的分离。其他和select类似,也是在指定时间内轮询一定数量的文件描述符,检测其中是否有就绪的。还是先从API说起。
poll API
函数原形:
# include <poll.h>
int poll ( struct pollfd * fds, unsigned int nfds, int timeout);
参数
poll函数的第一个参数fds是struct pollfd结构体类型的事件集,一般传入一个该类型的数组。
pollfd结构体定义如下:
struct pollfd {
int fd; /* 文件描述符 */
short events; /* 等待的事件 */
short revents; /* 实际发生了的事件,由内核填充 */
} ;
该结构体有三个成员:
第一个fds是要监听的文件描述符,
第二个events是要监听的事件(POLLIN、POLLOUT、POLLERR),
第三个revents是监控事件中满足条件返回的事件,内核通过修改这个参数来反馈监听的就绪事件。
事件主要有以下几个:
POLLIN 有数据可读。
POLLRDNORM 有普通数据可读。
POLLRDBAND 有优先数据可读。
POLLPRI 有紧迫数据可读。
POLLOUT 写数据不会导致阻塞。
POLLWRNORM 写普通数据不会导致阻塞。
POLLWRBAND 写优先数据不会
第二个参数nfds是监听的文件描述符的个数,
第三个参数timeout是设置超时时间,用法和select一样。是一个struct timeval结构体指针,该结构体定义如下:
struct timeval{
long tv_sec; //second
long tv_usec; //minisecond
}
超时时间可以设置到毫秒级别,有三种设置情况:
NULL:阻塞等待,直到某个文件描述符上发生了事件。
0:仅检测描述符集合的状态,然后立即返回。
> 0: 指定超时时间,如果在该时间段里没有事件发生,select将超时返回。
返回值