本文共 2828 字,大约阅读时间需要 9 分钟。
#includeint poll(struct pollfd fds[], nfds_t nfds, int timeout);
系统调用poll()执行的任务同很相似。两者间主要的区别在于我们要如何指定待检查的文件描述符。再select()中,我们提供三个集合,在每个集合中标明我们感兴趣的文件描述符。而在poll()中我们提供了一列文件描述符,并在每个文件描述符上标明我们感兴趣的事件。
fds:是一个struct pollfd结构类型的数组,列出了我们需要poll()检查的文件描述符,其定义如下:
typedef struct pollfd { int fd; /* 需要被检测或选择的文件描述符*/ short events; /* 对文件描述符fd上感兴趣的事件 */ short revents; /* 文件描述符fd上当前实际发生的事件*/} pollfd_t;
pollfd结构体中的events和revents字段都是掩码。调用者初始化events来指定需要为描述符fd做检查的事件。当poll()返回时,revents被设定以此来表示该文件描述符上实际发生的事件。
下表列出了events和revents字段中掩码:
位掩码 | events中的输入 | 返回到revents | |
POLLIN POLLRDNORM POLLRDBAND POLLPRI POLLRDHUB | ● ● ● ● ● | ● ● ● ● ● | 可读取非高优先级数据 等同于POLLIN 可读取优先级数据(linux中不可用) 可读取高优先级数据 对端套接字关闭 |
POLLOUT POLLWRNORM POLLWRBAND | ● ● ● | ● ● ● | 普通数据可写 等同于POLLOUT 优先级数据可写入 |
POLLERR POLLHUP POLLNVAL | ● ● ● | 有错误发生 出现挂断 文件描述符未打开 | |
POLLMSG | linux中不可用 |
一般来说,poll()真正关心的标志位是:POLLIN、POLLOUT、POLLPRI、POLLRDHUB、POLLHUP、POLLERR
nfds:指定了fds中元素的个数,nfds_t为无符号整形
timeout:决定阻塞行为,一般如下:
-1:一直阻塞到fds数组中有一个达到就绪态或者捕获到一个信号
0:不会阻塞,立即返回
>0:阻塞时间
和select()一样,timeout的精度收软件时钟粒度的影响,如果不是时间粒度整数倍,向上取整。
返回值:
>0:数组fds中准备好读、写或出错状态的那些socket描述符的总数量;
==0:数组fds中没有任何socket描述符准备好读、写,或出错;此时poll超时
-1: poll函数调用失败,同时会自动设置全局变量errno为下列值之一:
EBADF:一个或多个结构体中指定的文件描述符无效。
EFAULT:fds指针指向的地址超出进程的地址空间。 EINTR:请求的事件之前产生一个信号,调用可以重新发起。 EINVAL:nfds参数超出PLIMIT_NOFILE值。 ENOMEM:可用内存不足,无法完成请求。
/*********************************************在/root/pro/fd1 /root/pro/fd2中分别有内容,12345678和11223344**********************************************/#include#include #include #include #include #include #include #include #include #include #include #include #define BUFSIZE 1024int main(int argc, char *argv[]){ char buf[BUFSIZE]; int bytes; struct pollfd *pollfd; int i=0; int nummonitor=0; int numready; int errno; char *str; if(argc != 3) { fprintf(stderr,"Usage:the argc num error\n"); exit(1); } if((pollfd = (struct pollfd*)calloc(2, sizeof(struct pollfd))) == NULL) exit(1); for(i; i<2; i++) //初始化化struct pollfd结构 { str = (char*)malloc(14*sizeof(char)); memcpy(str,"/root/pro/",14); strcat(str,argv[i+1]);//注意,需要把路径信息放到str中 printf("str=%s\n",str); (pollfd+i)->fd = open(str,O_RDONLY); if((pollfd+i)->fd >= 0) fprintf(stderr, "open (pollfd+%d)->fd:%s\n", i, argv[i+1]); nummonitor++; (pollfd+i)->events = POLLIN; } printf("nummonitor=%d\n",nummonitor); while(nummonitor > 0) { numready = poll(pollfd, 2, -1); if ((numready == -1) && (errno == EINTR)) continue; else if (numready == -1) break; //poll真正错误,退出 printf("numready=%d\n",numready); for (i=0;nummonitor>0 && numready>0; i++) { if((pollfd+i)->revents & POLLIN) { bytes = read(pollfd[i].fd, buf, BUFSIZE); numready--; printf("pollfd[%d]->fd read buf:\n%s \n", i, buf); nummonitor--; } } } for(i=0; i
结果为:
转载地址:http://souyn.baihongyu.com/