异步操作之异步通知编程

原创 2012年03月29日 20:35:51

我们前面介绍了阻塞与非阻塞的相关操作,其中poll()函数提供了较好的解决设备访问的基址
,但是如果有了异步通知的整套基址就更加完整了。
这次我就和大家一起来探讨一下Linux驱动开发中的异步操作

 

 

异步操作的概念与作用:
 概念:一旦设备准备就绪,则主动通知应用程序,这样应用程序就不需要查询设备状态了
 ,这一点与硬件上的"中断"概念非常相似
 
 在原理上一个进程收到一个信号与处理器收到一个中断请求时一样的。而所谓
 异步通知就是指:一个进程不必通过任何操作来等待信号的到达,进程也不知道信号shi什么时候到达
 
 这与阻塞及非阻塞I/O区别很大,阻塞I/O意味着一直等待到设备可以访问,而非阻塞I/O中使用poll()意味着需要查询设备
 是否可以访问,而异步通知则意味着设备通知自身可
 
 
 
 
 
 
 
 
Linux异步通知编程:


 
Linux信号:
  Linux中异步通知通过信号来实现
  Linux信号表:见下图


  
  

除了SIGSTOP和SIGKILL两个信号外(这两个信号一定会被捕获),进程能够忽略或捕获其他的全部
  信号,一个信号被捕获的意思是当一个信号到达时有相应的代码处理它,如果一个信号没有被这个进程锁捕获,
  内核将采用默认处理
  
  
 信号的接收:
  在用户空间,为了捕获信号,可以使用signal()函数来设置对应信号的处理函数:
  void (*signal (int signum,void (*handler))(int))(int);
  
  通常把该函数原型分解为:
  typedef void (*sighandler_t)(int);
  sighandler_t signal(int signum,sighandler_t handler));

  第一个参数指定信号的值,
  第二个参数指定对前面信号值的处理函数,若为SIG_IGN,表示忽略该信号。
  若为SIG_DFL表示采用系统默认方式处理信号,若为用户自定义函数,则信号被捕捉到
  后此函数将被执行
  
  
  函数返回值:如果signal()调用成功,它返回最后一次为信号signum绑定的处理函数handler值,失败
  则返回SIG_ERR
  
  signal()捕获信号范例:
  void sigterm_handler(int signo)
  {
   printf("Have caught sig N.O. %d\n",signo);
   exit(0);
  }
  
  
  int main(void)
  {
  /*捕捉SIGINT信号(Ctrl+c)*/
   signal(SIGINT,sigterm_handler);
  /*捕捉SIGTERM信号,kill正在运行的程序将发出SIGTERM信号*/
   signal(SIGTERM,sigterm_handler);
   while(1);
   
   return 0;
  }
  
  
  
  sigaction()函数与signal()函数功能类似
  int sigaction(int signum,const struct sigaction t*act,struct sigaction *oldact)
  参数介绍:
   signum:为信号值
   act:为指向结构体sigaction的一个指针,在结构体signaction的实例中,指定对特殊信号的处理函数
    ,若为空则进程会以缺省的方式对信号进行处理
   oldact:用来保护原来的信号处理函数
   
   此函数使用的一个小技巧:把第二三个参数设为NULL,那么该函数
   可以用于检查信号的有效性
   
  在用户空间对设备释放信号的处理:
   (1).通过F_SETOWN IO控制命令设置文件的拥有者为本进程,这样从驱动发出的信号才能被本进程
    接收
    fcntl(STDIN_FILENO,F_SETOWN,getpid());
   (2).通过F_SETFLIO控制命令设置设备文件支持FASYNC,即异步通知模式
    oflags = fcntl(STDIN_FILENO,F_GETFL);//获取原有模式
    fcntl(STDIN_FILENO,F_SETEL,oflags | FASYNC);//设置异步通知模式
   (3).通过signal()函数连接信号和信号处理函数
   
   
   
  以上介绍的两个函数都是在用户空间对信号进行处理的函数,下面介绍一下信号处理的
  驱动程序设计
  
  
  
  首先介绍一下一个函数和一个结构体:
  int fasync_helper(int fd,struct file*filp,int mode,struct fasync_struct **fa)
  //此函数与用来处理FASYNC标识的变更,简单的说可以用来设置设备文件支持FASYNC模式,执行此函数后,通过
  fa就可以得知当前设备资源是否可以获得
  
  
  结构体:fasync_struct,对于此结构体的对象你不需要深入了解,这里你只需要知道,再执行上述函数
  后,一旦资源可获得,此结构体不为空,从下面的程序中你也可以看出
  
  
  
  信号的释放:
   在设备驱动和应用程序的异步通知交互中,仅仅在应用程序端捕获信号是不够的,因为信号的源头在
   设备的驱动端,应该在合适的时候让设备驱动释放信号,在设备驱动程序中增加释放信号的相关代码
   
   
   支持设备异步通知机制的驱动程序编写:
   (1) 支持F_SETOWN命令,能在这个控制命令处理中设置filp->f_owner为对应进程ID(此工作已由内核实现)
   (2) 支持F_SETEL命令的处理,每当FASYNC标识改变时,驱动程序的fasync()函数将得以执行。此函数需要在驱动程序中实现
   static int xxx_fasync(int fd,struct file *filp,int mode)
   {
    struct xxx_dev *dev = filp->private_data;
    return fasync_helper(fd,filp,mode,&dev->async_queue);
   }
   (3)在设备资源可获得时,调用kill_fasync()函数激发响应信号
   例如:
   static ss_size_t xxx_write(struct file*filp,const char __user *buf,size_t count,loff_t *f_pos)
   {
    struct xxx_dev *dev = filp->private_data;
    ...
    /*产生异步读信号*/
    if(dev->async_queue)
     kill_fasync(&dev->async_queue,SIGIO,POLL_IN);
     ...
   }

  
   //驱动程序中的这三步操作正好对应于用户空间的那三步操作
   
   具体如图所示:
   
   
   
   
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  

版权声明:本文为博主原创文章,未经博主允许不得转载。

vc6操作PostgreSQL 测试下异步通知接口

这个异步通知还很有用,就是一旦表里有数据写入了,马上通知你做其他什么事情 例子官方的是linux 的, 改成windows 吧,毕竟使用这个的人太少,霍霍 距离任务设定越来越短。接近完工鸟...

07-S3C2440驱动学习(一)嵌入式linux字符设备驱动-按键驱动程序之异步通知机制+原子操作+互斥信号量+阻塞与非阻塞+定时器去抖

一、异步通知机制 从按键的实现方式来说,可以分为以下几种方式 查询方式,极度耗费CPU资源中断方式,平时休眠,按键按下,唤醒休眠poll机制,不需要一直read,根据poll返回值来决定是否rea...

【Linux 驱动】第六章 高级字符驱动程序操作----异步通知

一,概念          异步通知:一旦设备就绪,则主动通知应用程序,应用程序根本就不需要查询设备状态。(类似于中断)信号是异步的,一个进程不必通过任何操作来等待信号的到达       ...

Linux设备驱动程序学习(6)-高级字符驱动程序操作[(4)异步通知fasync]

异步通知fasync 异步通知fasync是应用于系统调用signal和sigaction函数,下面我会使用signal函数。简单的说,signal函数就是让一个信号与与一个函数对应,没当接...
  • tigerly
  • tigerly
  • 2014年04月03日 15:23
  • 320

高级字符驱动程序操作之异步通知IO(实践篇)基于内核2.6.35-30

1. async.c 主要展示异步通知机制在驱动程序中的实现 #include #include #include /* everything... */ #includ...

Linux异步通知编程(转)

1.Linux信号http://www.ibm.com/developerworks/cn/linux/l-ipc/part2/index1.htmlhttp://www.ibm.com/develo...
  • lgb571
  • lgb571
  • 2011年05月12日 14:28
  • 1532

网络编程(52)—— Windows下使用WSAEventSelect实现异步通知IO

一、同步IO和异步IO         同步IO是指发生IO事件的时间点和相关函数返回的时间点一致。如使用send函数发送数据时,所有的数据发送到输出缓冲区后,send函数才会返回,这种IO方式就是同...

linux 设备驱动异步通知总结

  • 2016年02月18日 15:18
  • 16KB
  • 下载

linux驱动编程--异步通知与异步I/O

@signal for software is equal to @interrupt for hardware.(信号是软件上对于中断的模拟)
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:异步操作之异步通知编程
举报原因:
原因补充:

(最多只允许输入30个字)