Chinaunix首页 | 论坛 | 博客
  • 博客访问: 113250
  • 博文数量: 23
  • 博客积分: 471
  • 博客等级: 一等列兵
  • 技术积分: 251
  • 用 户 组: 普通用户
  • 注册时间: 2010-12-21 15:21
文章分类
文章存档

2017年(1)

2013年(2)

2011年(20)

分类: LINUX

2011-08-21 09:27:51

4.异步通知
 
  4.1应用程序角度考虑
 
   应用程序为了启用文件的异步通知机制,必须执行两个步骤:
 
   1.指定一个进程作为文件的"属主",进程可以使用fcntl执行F_SETOWN命令(此时进程id号被保存在filp->f_owner中),目的是为了让内核知道应该通知哪个进程。
   2.用户通过fcntl的F_SETFL命令设置FASYNC标志。
 
   执行完上述两个步骤后,输入文件可以在数据到达时请求发送一个ISGIO信号(驱动程序发送),该信号发送到存放在filp->f_owner中的进程。
 
如下示例代码启用stdin文件的异步通知机制:
  1. signal(SIGIO,&input_handler);
  2. fcntl(STDIN_FILENO,F_SETOWN,getpid());
  3. oflags = fcntl(STDIN_FILENO,F_GETFL);
  4. fcntl(STDIN_FILENO,F_SETFL,oflags | FASYNC);

应用程序中还有两点注意:应用程序不是所有设备都支持异步通知,通常应用程序假设只有套接字和终端才有异步通知能力;如果有多个文件可以异步通知输入的进程,应用程序需要借助poll或者select来确定输入的来源(利用FD_ISSET来判断)。

4.2 驱动程序角度考虑

    那么驱动程序如何来实现异步信号呢?

    内核已经提供了很方便的函数给我们使用,为了实现异步信号,驱动程序需要做三件事情:

    1.实现fasync方法:该方法也只需要做一步,调用内核提供的fasync_helper函数,如下是scullp设备提供的实现代码:

  1. static int scull_p_fasync(int fd, struct file *filp,int mode)
  2. {
  3.    struct scull_pipe *dev = filp->private_data;
  4.    return fasync_helper(fd,filp,mode,&dev->async_queue);
  5. }

   2.当数据到达时,需要实现异步通知,这时需要调用kill_fasync,当数据可读时,此时需要通知应用程序数据可读,如下是scullp设备提供的代码:

  1. if(dev->async_queue)
  2.    kill_fasync(&dev->async_queue,SIGIO,POLL_IN);

如果是为写入提供异步信号,kill_fasync必为模式调用POLL_OUT。

    3.在文件关闭时必须调用fasync方法,以便从活动的异步读取进程列表中删除该文件,所有在close方法中有如下调用:

  1. sucll_p_fasync(-1,filp,0);
阅读(1553) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~