0%

IO多路复用 poll 入门

[TOC]

概述

poll机制的工作原理及流程与select类似,但poll可监控的进程数量不受select中第二个因素——fd_set集合容量的限制,用户可在程序中自行设置被监测的文件描述符集的容量,当然poll在阻塞模式下也采用轮询的方式监测文件描述符集,因此应合理设置poll中监控进程的数量。poll机制主要通过poll()函数实现,下面对poll()函数进行讲解。

poll和select基本上可以认为,唯一的区别就是 pool 没有 FD_SETSIZE 的限制,用户可自定义打开的连接数量,其他的都完全一样,如何阻塞

poll 系统调用

1
int poll(struct pollfd *fds, nfds_t nfds, int timeout);

poll()函数中参数fds是一个struct pollfd类型的指针,主要用于传入被监测的多个文件描述符,其数据类型struct pollfd的定义如下:

1
2
3
4
5
struct pollfd{
int fd; //文件描述符
short events; //等待的事件
short revents; //实际发生的事件
}

该结构体中的成员fd表示文件描述符,当将fd设置为-1时,表示取消对该文件描述符的监测;成员events用于设置程序等待的事件,该值由用户主动设置;成员revents用于设置文件描述符的操作结果对应的事件,该值在函数返回时被设置。poll可能涉及的事件及其对应的宏如表1所示。

事件 事件说明
POLLIN 文件描述符中有数据可读(包括普通数据或优先数据)
POLLRDNORM 文件描述符中有普通数据可读
POLLRDBAND 文件描述符中有优先数据可读
POLLPRI 文件描述符中高优先级数据可读
POLLOUT 文件描述符中有数据可写(包括普通数据或优先数据)
POLLWRNORM 文件描述符中可写入普通数据
POLLWRBAND 文件描述符中可写入优先数据
POLLERR 发生错误事件
POLLHUP 发生挂起事件
POLLNVAL 非法请求

poll()函数中的参数nfds等同于select()函数中的参数nfds,用来设置pollt监控的文件描述符的范围,需设置为文件描述符最大值加1;

参数timeout与select()函数中的参数timeout,都用于设置组设时长,但其取值略有差异,poll()函数中参数timeout的取值及其对应含义如下:

● 当timeout=-1时,poll()函数阻塞等待;

● 当timeout=0时,poll()函数将立即返回,以轮询的方式监测文件描述符表;

● 当timeout>0时,等待指定时长(单位为毫秒,若当前系统时间精度不够毫秒则向上取值)。

返回值

poll()函数若调用成功将返回就绪文件描述符数量;若等待超时,将返回0,表示没有已就绪的文件描述符;若调用出错,将返回-1,并设置errno。

参考

pool