目录
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
1. 历史地位
跨平台不如select,性能不如epoll,比较尴尬的地位。
2. 作用
IO多路转接能够同时等待多个文件描述符的就绪状态,换句话说,可以帮助我们同时监控多个文件描述符。
3. 接口
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
3.1 参数
- fds:事件结构数组,存放监控的文件描述符,关心的事件(例如关心文件的可读事件,可写事件,可读事件例如调用recv函数的话那么必须要当接收缓冲区中有内容才可以IO(IO的本质其实就是等待与读取),又例如可写事件,必须要等),真实产生的事件。
- nfds:描述fds数组当中有多少有效元素。也就是我们要关心在事件结构数组中的多少个元素。
- timeout:超时事件单位s
- >0:表示带有超时时间的等待。
- ==0:非阻塞,需要搭配循环来使用。
- <0:阻塞监控
3.2 返回值
- >0∶表示多少文件描述符就绪。
- ==O:监控超时。
- <0∶监控出错。
- 例如:无效的文件描述符。
3.3 事件结构(也就是在事件结构数组中存放的元素)
struct pollfd {
int fd; /* file descriptor */要监控的文件描述符。
short events; /* requested events */关心文件描述符产生的事件: POLLIN:可读事件, POLLOUT:可写事件如果想要监控多个事件,则使用按位或的方式。
short revents; /*returned events*/文件描述符真实产生的事件。可能产生POLLIN事件也可能产生POLLOUT事件,那么我们可以判断revents==POLLIN还是==POLLOUT来获取我们关心的事件。
};
3.4 代码演示
我们写一个监控0号文件描述符的poll程序:
运行:
4.poll的优缺点
4.1 优点
1.提出了事件结构的方式,在给poll函数传递参数的时候,不需要分别添加到“事件集合”当中。select需要将要监控的事件添加到事件集合中,而poll这里只需要自己创建监控事件的数组,然后给其中的成员赋值。
2.事件结构数组的大小可以根据程序员自己进行定义,并没有上限的要求。select最大的可监控事件数目为1024个文件描述符。而poll这里可以自定义事件结构数组。然后对数组元素进行赋值。
3.不用在监控到就绪之后,重新添加文件描述符。而select则需要每次监控之后将事件集合更新
4.2 缺点
1.不支持跨平台
2.内核也是对事件结构数组监控的时候采用轮询遍历的方式。