在终端中输入 man 2 poll 就可以知道poll函数的具体应用方法
select函数的不足:内核必须检查多余的文件描述符,每次调用select()之后必须重置被监听的文件描述符集合,而且可监听的文件描述符的个数受限制,相比较后,poll函数对于监听具有更好的应用价值。
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <poll.h>#define MAX_BUFFER_SIZE 1024 /* 缓冲区大小*/
#define IN_FILES 3 /* 多路复用输入文件数目*/
#define TIME_DELAY 60 /* 超时时间秒数 */
#define MAX(a, b) ((a > b)?(a):(b))int main(void)
{struct pollfd fds[IN_FILES]; //Data structure describing a polling requestchar buf[MAX_BUFFER_SIZE];int i, res, real_read, maxfd;/*首先按一定的权限打开两个源文件*/fds[0].fd = 0;if((fds[1].fd = open ("in1", O_RDONLY|O_NONBLOCK)) < 0){printf("Open in1 error\n");return 1;}if((fds[2].fd = open ("in2", O_RDONLY|O_NONBLOCK)) < 0){printf("Open in2 error\n");return 1;}/* 指定监听那些文件类型的事件*/for (i = 0; i < IN_FILES; i++){fds[i].events = POLLIN; //There is data to read 指定监听可以读取的文件类型的}/*循环测试该文件描述符是否准备就绪,并调用select函数对相关文件描述符做对应操作*/while(fds[0].events || fds[1].events || fds[2].events){if (poll(fds, IN_FILES, 0) < 0){printf("Poll error\n");return 1;}for (i = 0; i< IN_FILES; i++){if (fds[i].revents) //如果发生变化,可读时 则返回true{memset(buf, 0, MAX_BUFFER_SIZE);real_read = read(fds[i].fd, buf, MAX_BUFFER_SIZE);if (real_read < 0){if (errno != EAGAIN){return 1;}}else if (!real_read){close(fds[i].fd);fds[i].events = 0;}else{if (i == 0){if ((buf[0] == 'q') || (buf[0] == 'Q')){return 1;}}else{buf[real_read] = '\0';printf("%s", buf);}} /* end of if real_read*/} /* end of if revents */} /* end of for */} /*end of while */exit(0);
}
验证方法: 1】首先一定要在同一个工作目录下
2】然后分别在当前工作目录中打开两个终端创建两个管道文件
在第一个终端1中 两条命令(1)mknod in1 p (2)cat>in1
在第二个终端2中 两条命令(1)mknod in2 p (2)cat>in2
3】在当前目录中打开第三个终端3运行上面程序的可执行文件
4】在终端1或者终端2中随意输入字符,观察终端3的变化情况
5】在终端3中输入Q或q 将会退出