API
poll系统调用和select类似,也是在指定时间内轮询一定数量的文件描述符,以测试其中是否有就绪者,poll原型如下:
#include <poll.h>
int poll(struct pollfd *ufds, unsigned int nfds, int timeout);
pollfd结构体如下:
struct pollfd {
int fd; //文件描述符
short events; //要求查询的事件掩码
short revents; //返回的事件掩码
};
- fd : 要测试的文件描述符
- events: 要测试的条件
- revents: 返回该描述符的状态
poll函数参数:
*ufds:是要监控的文件句柄集合,使用pollfd类型的结构来监控一组文件句柄
nfds:是监控的文件句柄数量
timeout:是等待的毫秒数,这段时间内无论I/O是否准备好,poll都会返回。timeout为<0表示无限等待,timeout为0表示调用后立即返回。
返回值:超时返回0,发生错误返回-1,有事件发生返回就绪描述符个数
在文件句柄中可监控的事件如下:
常值 | 说明 |
---|---|
POLLIN | 有数据可读。 |
POLLRDNORM | 有普通数据可读。 |
POLLRDBAND | 有优先数据可读。 |
POLLPRI | 高优先级数据可读。 |
POLLOUT | 写数据不会导致阻塞。 |
POLLWRNORM | 写普通数据不会导致阻塞。 |
POLLWRBAND | 写优先数据不会导致阻塞。 |
POLLERR | 发生错误(只可在revents中返回) |
POLLRDHUP | TCP连接被对方关闭,或者对方关闭了写操作 |
POLLHUP | 发生挂起(只可在revents中返回) |
POLLNVAL | 描述符不是一个打开的文件(只可在revents中返回) |
poll特点:
- 统一处理所有事件类型,通过pollfd.events传入感兴趣的事件,通过pollfd.revents返回就绪事件
- 轮询方式检测就绪事件,算法复杂度为O(n)
- 监听的文件描述符个数可以达到系统允许打开的最大描述符个数,65535(/proc/sys/fs/file_max)
编码
#include <sys/poll.h>
#include <sys/time.h>
int main()
{
int fd;
struct pollfd fds[2];
fds[0].fd = fd;
fds[0].events = POLLIN;
while(1)
{
ret = poll(fds, 1, &timeout);
if ( -1 == ret)
{
printf("error\n");
return -1;
}
else if ( 0 == set)
{
printf("select timout,continue\n");
break;
}
else if ( ret > 0 )
{
if ( fds[0].revents & POLLIN )
{
dealwithEvent(fd);
}
}
}
}