异步操作之异步通知编程

原创 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);
     ...
   }

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

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

相关文章推荐

异步操作之异步通知编程

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

异步通知与异步I/O http://blog.sina.com.cn/s/blog_4a70d5d901012oea.html

异步通知:很简单,一旦设备准备好,就主动通知应用程序,这种情况下应用程序就不需要查询设备状态,这是不是特像硬件上常提的“中断的概念”。上边比较准确的说法其实应该叫做“信号驱动的异步I/O”,信号是在软...

我是如何成为一名python大咖的?

人生苦短,都说必须python,那么我分享下我是如何从小白成为Python资深开发者的吧。2014年我大学刚毕业..

linux下使用异步通知

阻塞式I/O是一直等待直到设备可以访问,非阻塞式I/O是定期轮询设备是否可以访问。 异步通知则是当设备可以访问时才主动通知应用程序,有点像设备的硬中断。   并不是所有的设备都支持异步通知,应用程序通...

2440 异步通知的代码的实现

在2440开发板上面实现了 异步通知IO的。

异步通知

介绍用户层的异步通知的使用和驱动层的支持

异步通知

要弄明白这个问题,我们得从最基本的原理开始。我们知道,驱动程序运行在内核空间中,应用程序运行在用户空间中,两者是不能直接通信的。但在实际应用中,在设备已经准备好的时候,我们希望通知用户程序设备已经ok...

异步通知

异步通知: 使用异步通知机制可以提高查询设备的效率。通过使用异步通知,应用程序可以在数据可用时收到一个信号,而无需不停地轮询。 设置异步通知的步骤(针对应用层来说的): 1.首先制定一个进程作为...

异步通知

http://blogold.chinaunix.net/u1/43728/showart_343849.html这哥们写的比较清楚,收藏了!要弄明白这个问题,我们得从最基本的原理开始。我们知道,驱动...

异步通知

要弄明白这个问题,我们得从最基本的原理开始。我们知道,驱动程序运行在内核空间中,应用程序运行 在用户空间中,两者是不能直接通信的。但在实际应用中,在设备已经准备好的时候,我们希望通知用户 程序设备...

异步通知

要弄明白这个问题,我们得从最基本的原理开始。我们知道,驱动程序运行在内核空间中,应用程序运行在用户空间中,两者是不能直接通信的。但在实际应用中,在设备已经准备好的时候,我们希望通知用户程序设备已经ok...
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

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