I/O复用——poll系统调用

来源:互联网 发布:聊天软件默默 编辑:程序博客网 时间:2024/06/06 16:57

poll系统调用

  poll系统调用和select类似,也是在指定时间内轮询一定数量的文件描述符,以测试其中是否有就绪的文件描述符。

  在终端输入man poll可查看poll函数的原型:

#include <poll.h>int poll(struct pollfd *fds, nfds_t nfds, int timeout);

 1)fds参数是一个pollfd结构类型的数组,它指定所有我们感兴趣的文件描述符上发生的可读、可写和异常事件。pollfd结构体的定义如下:

struct pollfd {    int   fd;      /* file descriptor (文件描述符) */    short events;  /* requested events (注册的事件) */    short revents; /* returned events (实际发生的事件,由内核填充) */};

  其中,fd成员指定文件描述符;events成员告诉poll监听fd上的哪些事件,它是一系列事件的按位或;revents成员则由内核修改,以通知应用程序fd上实际发生了哪些事件。

  poll支持的事件类型如下表所示:

事件描述是否可作为输入是否可作为输出POLLIN数据(包括普通数据和优先数据)可读是是POLLRDNORM普通数据可读是是POLLRDBAND优先级带数据可读(Linux不支持)是是POLLPRI高优先级数据可读,比如TCP带外数据是是POLLOUT数据(包括普通数据和优先数据)可写是是POLLWRNORM普通数据可写是是POLLWRBAND优先级带数据可写是是POLLRDHUPTCP连接被对方关闭,或者对方关闭了写操作。它由GNU引入是是POLLERR错误否是POLLHUP挂起。比如管道的写端被关闭后,读端描述符上将收到POLLHUP事件否是POLLNVAL文件描述符没有打开否是

  上表中,POLLRDNORM、POLLRDBAND、POLLWRNORM、POLLWRBAND由XOPEN规范定义。它们实际上是将POLLIN事件和POLLOUT事件分得更细致,以区别对待普通数据和优先数据。但Linux并不完全支持它们。

  通常,应用程序需要根据recv调用的返回值来区分socket上接收到的是有效数据还是对方关闭连接的请求,并做相应的处理。不过,自Linux内核2.6.17开始,GNU为poll系统调用增加了一个POLLRDHUP事件,它在socket上接收到对方关闭连接的请求之后触发。这为我们区分上述两种情况提供了一种更简单的方式。但使用POLLRDHUP事件时,我们需要在代码最开始处定义_GNU_SOURCE。

 2)nfds参数指定被监听事件集合fds的大小。其类型nfds_t的定义如下:

typedef unsigned long int nfds_t;

 3)timeout参数指定poll的超时值,单位是毫秒。当timeout为-1时,poll调用将永远阻塞,直到某个事件发生;当timeout为0时,poll调用将立即返回。

  poll系统调用的返回值含义与select相同。

0 0