Poll
select使用三个位图来表示三个fd_set的方式。
而poll是使用一个pollfd的指针实现。
select总结:http://blog.csdn.net/sayhello_world/article/details/72875077
poll函数
该函数允许进程指示内核等待多个事件中任何一个发生,并只在有一个或多个事件发生的时候才唤醒。
poll函数原型
#include <poll.h>
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
这里pollfd是一个结构体。
struct pollfd {
int fd; /* file descriptor */
short events; /* requested events */
short revents; /* returned events */
};
fds:是一个struct pollfd结构体类型的数组,用于存放需要检测其状态的socket描述符。
nfds:用于标记fds中的结构体元素的总数量。
timeout:poll函数的阻塞时间,单位是毫秒。—–注意区别select的timeout,两者类型不同。
timeout == 0:poll立即返回不阻塞,
timeout > 0:阻塞的毫秒数
timeout ==-1:poll一直阻塞,直到检测到socket描述符上关心的事件发生才返回。
poll函数返回值
大于0表示数组fds中准备就绪的socket描述符总量;
等于0表示超时返回;
等于-1表示出错返回。
poll的应用
用poll写一个服务器。
#include<stdio.h>
#include<stdlib.h>
#include<poll.h>
int main()
{
struct pollfd _poll;
_poll.fd = 0;
//只关心读事件
_poll.events = POLLIN;
_poll.revents = 0;
//阻塞等待
int timeout = -1;
while(1)
{
switch(poll(&_poll,1,timeout))
{
case 0:
printf("time out\n");
break;
case -1:
perror("poll");
break;
//有数据
default:
{
char buf[1024];
ssize_t s = read(0,buf,sizeof(buf));
if(s > 0)
{
buf[s] = 0;
printf("%s\n",buf);
}
printf("read ready\n");
}
}
}
}
poll的优缺点
poll的优点:
poll()系统调用是System V的多元I/O解决方案。
它有三个参数,第一个是pollfd结构的数组指针,也就是指向一组fd及其相关信息的指针,因为这个结构包含的除了fd,还有期待的事件掩码和返回的事件掩码。
实质上就是将select的中的fd,传入和传出参数归到一个结构之下,也不再把fd分为三组,也不再硬性规定fd感兴趣的事件,这由调用者自己设定。
这样,不使用位图来组织数据,也就不需要位图的全部遍历了。
按照一般队列地遍历,每个fd做poll文件操作,检查返回的掩码是否有期待的事件,以及做是否有挂起和错误的必要性检查,如果有事件触发,就可以返回调用了。
poll的缺点:
poll对于select来说包含了一个pollfd结构,pollfd结构包含了要监视的event和发生的revent,而不像select那样使用参数-值的传递方式。同时poll没有最大数量的限制。但是仍存在以下缺点
1、数量过大以后其效率也会线性下降。
2、poll和select一样需要遍历文件描述符来获取已经就绪的socket。当数量很大时,开销也就很大。