zoukankan      html  css  js  c++  java
  • linux异步通知

    简述

    linux下异步方式有两种:异步通知和异步IO(AIO),aio请参考:linux异步IO--aio

    异步通知的含义是:一旦设备就绪,则主动通知应用程序,这样应用程序就不需要查询设备状态,准确称谓是“信号驱动的异步I/O”。

    Linux的I/O机制经历了一下几个阶段的演进:

    1. 同步阻塞I/O: 用户进程进行I/O操作,一直阻塞到I/O操作完成为止。

    2. 同步非阻塞I/O: 用户程序可以通过设置文件描述符的属性O_NONBLOCK,I/O操作可以立即返回,但是并不保证I/O操作成功。

    3. 异步事件阻塞I/O: 用户进程可以对I/O事件进行阻塞,但是I/O操作并不阻塞。通过select/poll/epoll等函数调用来达到此目的。

    4. 异步时间非阻塞I/O: 也叫做异步I/O(AIO),用户程序可以通过向内核发出I/O请求命令,不用等待I/O事件真正发生,可以继续做另外的事情,等I/O操作完成,内核会通过函数回调或者信号机制通知用户进程。这样很大程度提高了系统吞吐量。

    阻塞IO意味着一直等待设备可访问后再访问,非阻塞IO中使用poll()意味着查询设备是否可访问,而异步通知则意味着设备通知自身可访问,实现了异步IO。

    实现

    异步通知在linux下实现分为两部分:应用层和内核驱动层。

    应用层主要处理signal部分(signal编程),处理步骤如下:

    1. 通过F_SETOWN IO控制命令(fcntl(fd, F_SETOWN, getpid()))设置设备文件的拥有者为本进程,这样从设备驱动发出的信号才能被本进程接收到。

    2. 通过F_SETFL IO控制命令(fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | FASYNC))设置文件支持FASYNC,即异步通知模式。

    3. 通过signal()函数连接信号和信号处理函数。

    内核驱动层处理步骤:

    1. 支持F_SETOWN命令,能在这个控制命令处理中设置filp->f_owner为对应进程ID。内核已完成。

    2. 支持F_SETFL命令的处理,每当FASYNC标志改变时,驱动程序中的fasync()函数将执行。

    3. 在设备资源可获得时,调用kill_fasync()函数激发相应的信号。

    设备驱动中异步通知编程涉及一项数据结构和两个函数,数据结构是fasync_struct,两个函数分别是:

    处理FASYNC标志变更的:

    int fasync_helper(int fd, struct file *filp, int mode, struct fasync_struct **fa);

    释放信号函数:

    void kill_fasync(struct fasync_struct **fa, int sig, int band);

    sig为SIGIO,band可读时POLL_IN,可写时POLL_OUT。

    和其他设备驱动一样,将fasync_struct结构体指针放在设备结构体中仍然是最佳选择。

    参考:

    1. Linux 异步IO机制

  • 相关阅读:
    Raphael入门
    EXT使用SASS修改主题样式问题
    Hough Transform Performance article List
    about utf8 ...
    computer vision resource
    Asp.net 中配置 CKEditor和CKFinder
    压缩格式 zip与tar.gz 区别
    一系列按钮的弹出提示框借助jq实现
    SQL Server2005 sa登录出错~
    正则表达式整理
  • 原文地址:https://www.cnblogs.com/embedded-linux/p/8596704.html
Copyright © 2011-2022 走看看