现在的位置: 首页 > 综合 > 正文

poll学习笔记

2013年07月09日 ⁄ 综合 ⁄ 共 2233字 ⁄ 字号 评论关闭

poll函数

  poll函数起源于SVR3,最初局限于流设备。SVR4取消了这种限制,允许poll工作在任何描述字上。poll提供的功能与select类似,不过在处理流设备时,它能够提供额外的信息。

#include <poll.h>
int pollresult = poll(struct pollfd *fdarray, unsigned long nfds, int timeout);

第一个参数fdarray是指向一个结构数组第一个元素的指针。每个数组元素都是一个pollfd结构:

struct pollfd{
  int fd;              //descriptor to check
  short events;    //events of interest on fd
  short revents;   //events that occurred on fd
};

结构数组中的 events 成员指定要测试的条件,而返回的结果则在保存在 revents。常用条件及含意说明如下:

poll函数可用的测试值

常量 说明
POLLIN 普通或优先级带数据可读
POLLRDNORM 普通数据可读
POLLRDBAND 优先级带数据可读
POLLPRI 高优先级数据可读
POLLOUT 普通数据可写
POLLWRNORM 普通数据可写
POLLWRBAND 优先级带数据可写
POLLERR 发生错误
POLLHUP 发生挂起
POLLNVAL 描述字不是一个打开的文件

注意:后三个只能作为描述字的返回结果存储在revents中,而不能作为测试条件用于events中。

第二个参数nfds是用来指定数组fdarray的长度。

最后一个参数timeout是指定poll函数返回前等待多长时间。它的取值如下:

timeout值 说明
-1 永远等待
0 立即返回,不阻塞进程
>0 等待指定数目的毫秒数


返回的结果pollresult 

 -1 poll函数调用失败
 0 在timeout内,数组fdarray中没有任何文件描述符准备好读、写或出错,poll函数正常超时返回。
 >0 数组fdarray中准备好读、写或出错状态的那些文件描述符的总数量

之后根据  fdarray[0].revents & POLLIN来判断是哪个发生了变化,之后直接read就可以了。

例子

#include <stdio.h>
#include <poll.h>
#include <linux/inotify.h>
#include <string.h>


#define OPEN_MAX 3
#define PATH_MAX 3
#define READ_MAX 1000


int main(int argc,char *argv[]){
  char *path = "/root/test/poll_test";
  char *paths[PATH_MAX] = {
    "/dev/input/event0",
    "/dev/input/event2"
   };
   struct pollfd client[OPEN_MAX];
   char read_buf[READ_MAX];

   struct inotify_event *event;
   char *event_buf[512]; 

   printf("poll_test ...\n");

   int fd = inotify_init();
   if(fd != -1){
     int wd = inotify_add_watch(fd,path,IN_DELETE | IN_CREATE);
     client[0].fd = fd;
     client[0].events = POLLIN;
     printf("open inotify\n");
   }else{
     printf("error:inotify can't open.\n");
     return -1;
   }

   int i;
   for(i = 1;i<OPEN_MAX; i++){
    fd = open(paths[i-1],O_RDWR);
    if(fd != -1){
      client[i].fd = fd;
      client[i].events = POLLIN;
      printf("open %s\n",paths[i-1]);
    }else{
      printf("error:%s can't open.\n",paths[i]);
      return -1;
    }
   }
        
   printf("ok. start loop.\n");
   int pollresult = 0;
   while(1){
      if(pollresult == -1){
        printf("error.\n");
        return -1;
      }else if(pollresult == 0){
      }else{
        if(client[0].revents & POLLIN){ //判断
           size_t len = read(client[0].fd,event_buf,512);
           event = (struct inotify_event *)(event_buf);
           if(event->mask & IN_CREATE){
              printf("notify:add %s \n",event->name);
           }else{
              printf("notify:delete %s \n",event->name);
           }
        }
        for(i = 1;i<OPEN_MAX;i++){
           if(client[i].revents & POLLIN){ //判断
              int readsize = read(client[i].fd,read_buf,READ_MAX);
              printf("read:%s\n",read_buf);
           }
        } 
      }
      printf("polling...\n");  
      pollresult = poll(client,OPEN_MAX,-1); //轮询
   } 
}


抱歉!评论已关闭.