linux下select和poll的用法[zz]

select( )函数的作用

系统用select和poll两个系统调用来查询设备是否可读写,或者是否处于某种状态。

如果poll为空,则驱动设备会被认为即可读又可写,返回值为一个状态掩码。

select( )函数原型:

     int select (int nfds, fd_set * readset, fd_set * writeset, fd_set * exceptset, struct timeval * timeout);

其中:

   nfds:  需要检查的文件描述符的个数,数值应该比之后三组fd_set中最大数更大,而不是实际文件描述符的总数。

   readset : 用来检查可读性的一组文件描述符。

   writeset : 用来检查可写性的一组文件描述符。

   exceptset: 用来检查意外状态的文件描述符。

   timeout : NULL 指针代表无限等待,否则是指向timeval结构的指针,代表最长等待时间。

函数返回值: 响应操作的对应操作文件描述符的总数,且三组数据均在恰当位置被修改,只有响应操作的那些没有修改。

接着应该用FD_ISSET宏来查找返回的文件描述符组。

类型 fd_set

fd_set是一组文件描述符fd的集合。由于fd_set类型的长度在不同平台上不同,因此应该用一组标准的宏定义来处理此类变量:

  1. fd_set fd;  
  2. FD_ZERO(&set);             /*将set清零*/  
  3. FD_SET (fd, &set);        /*将fd加入set*/  
  4. FD_CLR (fd, &set);        /*将fd从set中清除*/  
  5. FD_ISSET(fd, &set);       /*如果fd在set中则真*/  

 一个例子:

Code:
  1. int isready ( int fd )  
  2. {  
  3.      int rc;  
  4.      fd_set fds;  
  5.      struct  timeval tv;  
  6.        
  7.       FD_ZERO (&fds);  
  8.       FD_SET (fd, &fds);  
  9.         
  10.       tv.tv_sec = tv.tv_usec =0;  
  11.       rc = select ( fd+1, &fds, NULL, NULL, &tv);  
  12.       // rc = select ( fd+1, &fds, NULL, NULL , NULL);  
  13.       if ( rc < 0 )  
  14.       {  
  15.           return -1;
  16.       }
  17.       return FD_ISSET (fd, &fds) ? 1 : 0;
  18. }
  19.    

上面的例子是一个判断一个文件描述符可读性的例子。

如果我们把NULL指针作为fd_set传入的话,这就表示我们对这种操作的发生不感兴趣,但select() 还是会等待直到其发生或者超过等待时间。
[译 者注:在Linux中,timeout指的是程序在非sleep状态中度过的时间,而不是实际上过去的时间,这就会引起和非Linux平台移植上的时间不 等问题。移植问题还包括在System V风格中select()在函数退出前会把timeout设为未定义的 NULL状态,而在BSD中则不是这样, Linux在这点上遵从System V,因此在重复利用timeout指针问题上也应该注意。]

Linux下select调用的过程:
1.用户层应用程序调用select(),底层调用poll())
2.核心层调用sys_select() ------> do_select()
最终调用文件描述符fd对应的struct file类型变量的struct file_operations *f_op的poll函数。
poll指向的函数返回 当前可否读写的信息
 1)如果当前可读写,返回读写信息。
 2)如果当前不可读写,则阻塞进程,并等待驱动程序唤醒,重新调用poll函数,或超时返回。
3.驱动需要实现poll函数。
当驱动发现有数据可以读写时,通知核心层,核心层重新调用poll指向的函数查询信息。
poll_wait(filp,&wait_q,wait)   
// 此处将当前进程加入到等待队列中,但并不阻塞在中断中使用wake_up_interruptible(&wait_q)唤醒等待队列
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值