多路io 之 poll机制
poll函数
(1)函数原型
#include <poll.h>
int poll(struct pollfd *fds, nfds_t nfds, int timeout);
int poll(struct pollfd fds[], nfds_t nfds, int timeout);
(2)功能
监听集合有没有动静,如果没有动静就阻塞
如果有动静就成功返回,返回值为集合中有动静的fd的数量。
(3)参数
1)fds:这个参数写为struct pollfd fds[]更好理解些,第一个参数要求传递一个struct pollfd结构体数组
这个数组就相当于select的文件描述符集合,只不过select是使用fd_set来定义的,而poll的集合是一个数组。
struct pollfd的成员: struct pollfd { int fd; :文件描述符 short events; :设置我们希望发生的事件,比如读事件,这个需要我们自己设置 short revents; :实际发生的事件,比如读事件,由poll机制自己设置 };
struct pollfd fds[2];
fds[0].fd = 0;
fds[0].events = POLLIN;//读事件(输入事件)
fds[1].fd = 3;
fds[1].events = POLLIN;//读事件(输入事件)
poll监听时如果没有动静就阻塞,有动静就不再阻塞,返回有动静的fd的数量。
如何知道是那些fd有动静
如果文件描述符“发生的事件”==“实际事件”,就说明希望的事件来了,就是对fd进行相应的“读或写”操作
使用举例:
if(fds[1].events == fds[1].revents)//如果相等,就说明fds[1].fd有动静。
{
//读写fds[1].fd
}
2)nfds:数组的元素个数。
3)timeout:超时时间,如果写的是
(a)-1:不设置超时,如果集合没有动静就一直阻塞下去,直到poll函数被信号中断(唤醒)或者集合有动静为止
(b)非-1值:比如3000(3000微妙),表示将超时时间设置为3秒也就是说poll超时时间的单位时微妙。
4)返回值
(a)返回-1:说明函数调失败,errno被设置。
· 如果是被信号中断从而导致出错返回-1时,errno被设置为EINTR,
· 如果不想被中断,要么重启poll的调用,要么忽略或者屏蔽这些信号。
(b)0:超时时间到,而且没有文件描述符有动静
(c)>0:返回有响应的文件描述符的数量
poll.c
#include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <string.h> #include <strings.h> #include <errno.h> #include <sys/time.h> #include <unistd.h> #include <poll.h> void print_err(char *str,int line,int err_no){ printf("%d,%s:%s\n",line,str,strerror(err_no) ); exit(-1); } int main(int argc, char const *argv[]) { int coord=0; int mousefd =-1; fd_set readfds; char buf[100]={0}; int ret= 0; struct timeval timeover; struct pollfd fds[2]; mousefd =open("/dev/input/mouse1",O_RDONLY); //可能Mouse0或2 if(mousefd == -1) print_err("open mouse0 fail",__LINE__,errno); fds[0].fd=0; fds[0].events=POLLIN; fds[1].fd=mousefd; fds[1].events=POLLIN; while(1){ label:ret =poll(fds,2,3000); if(ret == -1 && errno == EINTR) goto label; else if(ret == -1) printf("poll fail",__LINE__,errno); else if(ret>0){ if(fds[0].events == fds[0].revents){ bzero(buf,sizeof(buf)); ret = read(fds[0].fd,buf,sizeof(buf)); if(ret>0) printf("%s\n",buf); } if(fds[1].events == fds[1].revents){ bzero(&coord,sizeof(coord)); ret = read(fds[1].fd,&coord,sizeof(coord)); if(ret>0) printf("%u\n",coord); } }else if(ret ==0){ printf("time out\n"); } } return 0; }