Chinaunix首页 | 论坛 | 博客
  • 博客访问: 116157
  • 博文数量: 50
  • 博客积分: 2495
  • 博客等级: 大尉
  • 技术积分: 535
  • 用 户 组: 普通用户
  • 注册时间: 2010-09-04 11:44
文章分类
文章存档

2011年(20)

2010年(30)

我的朋友

分类: LINUX

2010-09-30 21:18:52

当应用程序需要进行对多文件读写时,常用到 pollSystem V)、selectBSD Unix)、 epoll(linux2.5.45开始)(没验证)系统调用配合使用。poll函数返回时,会给出一个文件是否可读写的标志,应用程序根据不同的标志读写相应的文件,实现阻塞或非阻塞的读写。这些系统调用功能相同: 允许进程来决定它是否可阻塞或非阻塞的读写一个或多个文件。这些调用都需要来自设备驱动中poll 方法的支持,poll返回不同的标志,告诉主进程文件是否可以读写,其原型(定义在 :
实现这个设备方法分两步:
 
1.使用poll_wait将等待队列添加到poll_table中。
#include
static inline void poll_wait (struct file *filp, wait_queue_head_t *wait_address, poll_table *P);
增加wait_queue_head_t等待队列到poll_tabl中。
 
2. 返回描述设备是否可读或可写的掩码。几个标志(通过 定义)用来指示可能的操作:
 
 
标志
含义
POLLIN
 
如果设备无阻塞的读,就返回该值(设备可读)
 POLLRDNORM
 
 通常的数据已经准备好,可以读了,就返回该值。通常的做法是会返回(POLLLIN|POLLRDNORA
(数据可读)
 POLLRDBAND
 如果可 以从设备读出带外数据,就返回该值,它只可在linux内 核的某些网络代码中使用,通常不用在设备驱动程序中
 POLLPRI
 如果可 以无阻塞的读取高优先级(带外)数据,就返回该值,返回该值会导致select报告文件发生异常,以为select八带外数据当作异常处理
 
 POLLHUP
 当读设 备的进程到达文件尾时,驱动程序必须返回该值,依照select的功能描述,调用select的进程被告知进程时可读的。
 
 POLLERR
 如果设 备发生错误,就返回该值。
 
POLLOUT
 如果设备可以无阻塞地写,就返回该值(设备可写)
 
 POLLWRNORM
 设备已经准备好,可以写了,就返回该值。通常地做法是(POLLOUT|POLLNORM
(数据可写)
 POLLWRBAND
 POLLRDBAND类似
 
设备和数据在使用上实际上没有任何差别,通常可读返回:POLLIN|POLLRDNORM,可写返回:POLLOUT|POLLWRNORM
应当重复一下 POLLRDBAND POLLWRBAND 仅仅对关联到 socket 的文件描述符有意义: 通常设备驱动不使用这些标志。
poll 的描述使用了大量在实际使用中相对简单的东西. 考虑 poll 方法的 scullpipe 实现:
static unsigned int scull_p_poll(struct file *filp, poll_table *wait)
{
struct scull_pipe *dev = filp->private_data;        unsigned int mask = 0;/*       * The buffer is circular; it is considered full        * if "wp" is right behind "rp" and empty if the        * two are equal.  */down(&dev->sem);        poll_wait(filp, &dev->inq,  wait);        poll_wait(filp, &dev->outq, wait);        if (dev->rp != dev->wp)                mask |= POLLIN | POLLRDNORM;  /* readable */up(&dev->sem);        return mask;}
这个代码简单地增加了 2 scullpipe 等待队列到 poll_table, 接着设置正确的掩码位, 根据数据是否可以读或写.
所示的 poll 代码缺乏文件尾支持, 因为 scullpipe 不支持文件尾情况. 对大部分真实的设备, poll 方法应当返回 POLLHUP 如果没有更多数据(或者将)可用. 如果调用者使用 select 系统调用, 文件被报告为可读. 不管是使用 poll 还是 select, 应用程序知道它能够调用 read 而不必永远等待, 并且 read 方法返回 0 来指示文件尾.
 
范例
static unsigned int mem_poll(struct file *filp,poll_table *wait)
{
struct scull_piple *dev =filp->private_data;
?//为什么要使用scull_piple, scull_piple是针对一片内存实现一个环形缓,用缓冲的目的是存储队列。
unsigned int mask =0;
 
/*把进程添加到等待队列*/
poll_wait(filp,&dev->inq,wait);
 
/*返回掩码*/
If(数据有效)
         mask=POLLIN|POLLRDNRM;/*设备可读*/
return mask;
}
Poll方法只是做一个登记,真正的阻塞发生在select.c中的do_select函数。
阅读(784) | 评论(0) | 转发(0) |
0

上一篇:理解scull设备

下一篇:Linux 同步方法剖析

给主人留下些什么吧!~~