I/O多路转接---poll
select函数的缺点(相对于poll和epoll而言)
- 每次调用select,都需要手动的设置fd集合,从接口使用角度不太方便.
- 每次调用select,都需要把fd集合从用户态拷贝到内核态,开销大
- 在内核需要遍历传递进来的fd,开销大
- 支持的文件描述符太小
poll函数在select的基础上,解决了两个缺点
a>poll所监视的文件描述符无上限.select之所以有限制,是因为它采用的是位图来储存的,而poll采用的是一个pollfd指针,基于链存储的,只要内存不受限制,理论上是没有其他限制的.
b>select每次调用,都需要手动设置fd集合,从接口角度来看,不方便.而poll将输入参数和输出参数分离开,用events来监测的fd,用revent来表示就绪的fd.
A>poll函数接口
#include <poll.h>
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
// pollfd结构
struct pollfd {
int fd; /* file descriptor */ /* 保存要监测的fd,由用户自己设定 */
short events; /* requested events */ /* 保存要监测的事件,如读、写,有用户设定 */
short revents; /* returned events */ /* 保存就绪事件,由内核设定 */
};
poll监控标准输入:
1 #include<stdio.h>
2 #include<unistd.h>
3 #include<poll.h>
4 int main(){
5 struct pollfd poll_fd;
6 poll_fd.fd = 0;
7 poll_fd.events = POLLIN;//数据可读
8 while(1){
9 //利用poll函数进行等待
10 int ret = poll(&poll_fd,1,0);//0表示阻塞式等
11 if(ret<0){
12 perror("poll");
13 break;
14 }
15 //如果poll返回了,就说明0号文件描述符已经就绪
16 char buf[1024] = {0};
17 ssize_t read_size = read(0,buf,sizeof(buf)-1);
18 if(read_size<0){
19 perror("read");
20 return 1;
21 }
22 if(read_size==0){
23 printf("read done!\n");
24 return 0;
25 }
26 buf[read_size] = '\0';
27 printf("%s \n",buf);
28 }
29 return 0;
30 }