Linux设备驱动程序 之 异步通知
尽管大多数时候阻塞型和非阻塞型操作的组合以及select方法可以有效的查询设备,但是某些时候用这种技术处理就效率不搞了;
例如:一个进程在低优先级执行长的循环计算,但又需要尽可能快的处理输入数据,如果该进程正在响应来自数据收集外设新观测的数据,则应该在新数据可用时理解知晓并处理;我们可以使用poll来检查,但是跟好的做法是通过异步通知,应用程序可以再数据可用时收到一个信号,而不需要不停的使用轮询来关注数据;
从应用程序的角度
启用文件的异步通知机制,用户程序必须执行两个步骤:
1. 需要制定一个进程作为文件的“属主(owner)”;当进程使用fcntl系统调用执行F_SETOWN命令时,属主进程的ID号就被保存在filp->f_owner中,这样做的目的是为了让内核知道该通知哪个进程;
2. 为了真正启用异步通知机制,用户程序还必须在设备中设置FASYNC标志,这是通过fcntl的F_SETFL命令完成的;
执行完这两个步骤之后,输入文件就可以在新数据到达时发送一个SIGIO信号,该信号被发送到存放在filp->f_owner中的进程,如果f_owner是负值,信号会被发送到该进程组;
使用事例如下:
signal(SIGIO, &input_handler);
fcntl(STDIN_FILENO, F_SETOWN, getpid());
oflags = fcntl(STDIN_FILENO, F_GETFL);
fcntl(STDIN_FILENO, F_SETFL, oflags|FASYNC);
不是所有设备都支持异步通知,我们可以选择不提供异步通知功能;应用程序通常假设只有套接字和终端才有异步通知能力;
当进程收到SIGIO信号时,并不知道是那个输入文件有了新的输入,如果有多个文件可以异步通知输入进程,则应用程序仍然需要借助poll或者select来确定输入的源;
从驱动程序角度
驱动程序实现异步通知的步骤如下:
1. F_SETOWN被调用时对filp->f_owner赋值;
2. 在执行F_SETFL启用FASYNC时,调用驱动程序的fasync方法,只要filp->f_flags中的FASYNC标志发生了变化,就会调用该方法,以便把这个变化通知驱动程序,使其能正确响应;文件打开时,FASYNC标志被默认为是清除的;
其中fasync方法即为file_operations中的fasync方法:
int (*fasync) (int, struct file *, int);
3. 当数据到达时,在所有注册为异步通知的进程都会被发送一个SIGIO信号;
驱动程序需要调用下面两个函数来完成异步通知功能:
int fasync_helper(int fd, struct file * filp, int on, struct fasync_struct **fapp)
void kill_fasync(struct fasync_struct **fp, int sig, int band)
当一个打开的文件的FASYNC标志被修改时,调用fasync_helper以便从相关的进程列表中增加或者删除文件;除了最后一个参数之外,其他参数都是提供给fasync方法相同的参数,可以直接传递;
在数据到达时,可以调用kill_fasync通知所有相关进程,它的参数包括要发送的信号(通常是SIGIO)和带宽(band),后者几乎总是POLL_IN,但是在网络待命中,可以用来发送紧急或者带外数据;
当文件关闭时必须调用fasync方法,以便从活动的异步读取进程列表中删除该文件;尽管调用只在filp->f_flags设置了FASYNC标志时才是必须的,但不管什么情况,调用它不会有坏处,并且也是普遍的实现方法;
Linux设备驱动程序 之 异步通知的更多相关文章
- 蜕变成蝶~Linux设备驱动之异步通知和异步I/O
在设备驱动中使用异步通知可以使得对设备的访问可进行时,由驱动主动通知应用程序进行访问.因此,使用无阻塞I/O的应用程序无需轮询设备是否可访问,而阻塞访问也可以被类似“中断”的异步通知所取代.异步通知类 ...
- Linux内核开发之异步通知与异步I/O(一)
“小王,听说过锦上添花吧..”我拍拍下王的头说. “还锦上添花你,为你上次提的几个东东,我是头上长包..”小王气愤地瞪着我. “啊,为啥这样呢,本来还特意拒绝了MM的月份,抽出时间打算给你说点高级的东 ...
- 【转】linux设备驱动程序中的阻塞机制
原文网址:http://www.cnblogs.com/geneil/archive/2011/12/04/2275272.html 阻塞与非阻塞是设备访问的两种方式.在写阻塞与非阻塞的驱动程序时,经 ...
- Linux设备驱动程序 第三版 读书笔记(一)
Linux设备驱动程序 第三版 读书笔记(一) Bob Zhang 2017.08.25 编写基本的Hello World模块 #include <linux/init.h> #inclu ...
- Linux设备驱动程序学习之分配内存
内核为设备驱动提供了一个统一的内存管理接口,所以模块无需涉及分段和分页等问题. 我已经在第一个scull模块中使用了 kmalloc 和 kfree 来分配和释放内存空间. kmalloc 函数内幕 ...
- Linux设备驱动程序学习----2.内核模块与应用程序的对比
内核模块与应用程序的对比 更多内容请参考Linux设备驱动程序学习----目录 1. 内核模块与应用程序的对比 内核模块和应用程序之间的不同之处: 大多数中小规模的应用程序是从头到尾执行单个任务,而模 ...
- 嵌入式Linux设备驱动程序:编写内核设备驱动程序
嵌入式Linux设备驱动程序:编写内核设备驱动程序 Embedded Linux device drivers: Writing a kernel device driver 编写内核设备驱动程序 最 ...
- linux设备驱动程序该添加哪些头文件以及驱动常用头文件介绍(转)
原文链接:http://blog.chinaunix.net/uid-22609852-id-3506475.html 驱动常用头文件介绍 #include <linux/***.h> 是 ...
- 教你写Linux设备驱动程序:一个简短的教程
教你写Linux设备驱动程序:一个简短的教程 http://blog.chinaunix.net/uid-20799298-id-99675.html
随机推荐
- MyEclipse eclipse console edit packageExplorer 颜色设置、个性化、常用设置
下列教程的图片是在 myeclipse2014 破解版上进行,会有些许不同,仅供参考! 1 编辑区颜色设置 主题设置 豆沙绿设置 RGB 203 233 207 2 console 3主题选择 4 去 ...
- VBA精彩代码分享-3
在开发VBA程序中,我们可能会需要用代码处理VBA工程,包括启用VBA工程访问,启用所有宏,动态插入代码,动态删除代码,动态添加引用和自动创建模块等等,本次的分享内容便以这些为主. 启用VBA工程访问 ...
- get_object_or_404返回404(400)
get_object_or_404:第一个参数为queryset,第二个参数必须以关键字的形式传递,否则报错
- vue统一注册组件
文件夹下面组件数量较多,如果每一个组件先import然后在 components,虽然灭有问题,但是会导致代码量大,而且不直观 解决办法: 将图元组件进行统一注册 新建一个pixels文件,文件里面的 ...
- AOP底层实现原理,动态代理如何动态
代理 指定另外一个主体代替原来的某个主体去执行某个事物 代理执行的人 需要代理的人 需要代理的事情是一定要做的 但是被代理的人没有时间或自己做的不专业 静态代理: 父母朋友帮忙物色找对象 代理人掌握需 ...
- 第三章、drf框架 - 序列化组件 | Serializer
目录 第三章.drf框架 - 序列化组件 | Serializer 序列化组件 知识点:Serializer(偏底层).ModelSerializer(重点).ListModelSerializer( ...
- 【2】Git仓库
一.获取 Git 仓库 初始化仓库 ##基于当前目录初始化仓库 $ git init ##指定demo目录初始化仓库 $ git init demo 克隆现有仓库 ##克隆现有的仓库,默认目录名:li ...
- Cacti-0.8.8b详细安装及配置步骤
1. Cacti环境安装 1.1 安装LAMP环境 安装LAMP环境,当然,如果你有兴趣可以采用编译,我线上Mysql是编译的,其余是yum安装的.在这次实验采用yum安装. 关闭i ...
- Django:常用字段、手动自动第三张表单、元信息
一.常用字段和非常用字段 二.手动,自动创建第三张表 三.元信息 四.defer和only 一.常用字段和非常用字段 -常用字段 AutoField int自增列,必须填入参数 primary_key ...
- linux和unix下crontab的使用
在LINUX中,周期执行的任务一般由cron这个守护进程来处理 [ps -ef | grep cron].cron读取一个或多个配置文件,这些配置文件中包含了命令行及其调用时间.cron的配置文件称为 ...