Chinaunix首页 | 论坛 | 博客
  • 博客访问: 9396186
  • 博文数量: 1747
  • 博客积分: 12961
  • 博客等级: 上将
  • 技术积分: 20060
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-09 11:25
个人简介

偷得浮生半桶水(半日闲), 好记性不如抄下来(烂笔头). 信息爆炸的时代, 学习是一项持续的工作.

文章分类

全部博文(1747)

文章存档

2024年(23)

2023年(26)

2022年(112)

2021年(217)

2020年(157)

2019年(192)

2018年(81)

2017年(78)

2016年(70)

2015年(52)

2014年(40)

2013年(51)

2012年(85)

2011年(45)

2010年(231)

2009年(287)

分类: LINUX

2010-11-23 14:07:58

  1. 用户程序必须执行两个步骤来使能来自输入文件的异步通知
    1. 指定一个进程作为文件的拥有者。
      当一个进程使用fcntl系统调用发出F_SETOWN命令,这个进程ID则被保存在filp->f_owner中。
    2. 用户进程必须设置设备使用异步通知的方式。
      通过fcntl调用,把FASYNC标志设置在 F_SETFL 中。
  2. 用户程序设置完使用异步通知后, 驱动当检测到新数据到达时就会发送SIGIO信号给filp->f_owner的进程。
  3. 范例

    fcntl(fd, F_SETSIG, SIG_MYSIG); //把当前设备文件fd上报的SIGIO作为自定义SIG_SOFTPOWEROFF的信号处理

    signal(SIG_MYSIG, ProcSIG_SIG_MYSIG); //对自定义的信号量建立处理句柄////sigaction

    int flags;
    fcntl(fd ,F_SETOWN, getpid()); //应用可以接收驱动的SIGURG或SIGIO信号
    flags = fcntl(fd, F_GETFL);
    fcntl(fd, F_SETFL, flags|FASYNC);//也可以在open函数使用O_ASYNC标志


驱动部分.内核角度看驱动时如何实现异步信号
  1. 当发出F_SETOWN, 只有一个赋值操作 filp->f_owner
  2. 当F_SETFL被执行来打开FASYNC,驱动的fasync方法被调用。
  3. 当数据到达,所有注册异步通知的进程必须获得一个SIGIO信号。
  • 第一步.内核提供了一个通用实现来维护一个动态数据结构来跟踪不同的异步读进程
    数据结构 struct fasync_struct.
    int fasync_helper(int fd, struct file *filp, int mode, struct fasync_struct **fa);
    void kill_fasync(struct fasync_strtuct **fa, int sig, int band);

    fasync_helper 用于 从相关的进程列表中添加或去除入口项。 当FASYNC标志被打开时,其他所有标志参数都被传递给fasync方法。

    kill_fasync方法用来通知相关进程。它的参数 时信号(常是SIGIO)/ band(常是POLL_IN)
  • 驱动中fasync方法范例

/* 当F_SETFL被执行来打开FASYNC,驱动的fasync方法被调用 */

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


/* 当数据到达,所有注册异步通知的进程必须获得一个SIGIO信号 */

...

    if (dev->async_queue)

        kill_fasync(&dev->async_queue, SIGIO, POLL_IN);

        /* 当要通知用户进程设备可被写入时,参数应当使用POLL_OUT */

...


/* 当设备被关闭或者去除FASYNC标志时,需要从异步列表中去除此用户进程 */

/* remove this filp from the asynchrounously notified filp's  */

scull_p_fasync(-1, filp, 0);























阅读(1681) | 评论(0) | 转发(0) |
0

上一篇:6.3. poll 和 select

下一篇:6.5. llseek

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