linux设备驱动--异步通知和异步I/O

来源:互联网 发布:永辉超市 知乎 编辑:程序博客网 时间:2024/05/24 00:16

1、异步通知的概念和作用

影响:阻塞--应用程序无需轮询设备是否可以访问

非阻塞--中断进行通知

即:由驱动发起,主动通知应用程序

2、linux异步通知编程

2.1 linux信号

作用:linux系统中,异步通知使用信号来实现

2.2 信号的处理函数在应用程序端捕获信号

signal()函数

例子:

//启动信号机制

signal(SIGIO,input_handler);

fcntl(STDIN_FILENO,F_SETOWN,getpid());//设置进程为STDIN_FILENO文件拥有者,没有这一步内核不知道应该将信号发给那个进程

oflags = fcntl(STDIN_FILENO,F_GETEL);//

fcntl(STDIN_FILENO,F_SETFL,oflags|FASYNC);//为了启用异步通知机制,还需要对设备设置FASYNC标志

while(1);// 最后进入一个死循环,仅为保持进程不终止,如果程序中没有这个死循环,会立即执行完毕

2.3 信号的释放 (在设备驱动端释放信号)

为了是设备支持异步通知机制,驱动程序中涉及以下3项工作

(1)、支持F_SETOWN命令,能在这个控制命令处理中设置filp->f_owner为对应的进程ID。不过此项工作已由内核完成,设备驱动无须处理。

(2)、支持F_SETFL命令处理,每当FASYNC标志改变时,驱动函数中的fasync()函数得以执行。因此,驱动中应该实现fasync()函数

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

设备驱动中异步通知编程:

(1)、fasync_struct加入设备结构体模板中

(2)、两个函数

处理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);

3、支持异步通知的globalfifo驱动

(1)、将异步结构体fasync_struct添加到globalfifo设备结构体信息

(2)、支持异步通知的globalfifo设备驱动的fasync()函数

(3)、支持异步通知的globalfifo设备驱动的写函数

(4)、增加异步通知后的globalfifo设备驱动的release()函数

写个应用程序,在用户空间验证globalfifo的异步通知

4、linux2.6异步I/O

同步I/O:linux系统中最常用的输入输出(I/O)模型是同步I/O,在这个模型中,当请求发出后,应用程序就会阻塞,知道请求满足

异步I/O:I/O请求可能需要与其它进程产生交叠

4.1、AIO系列API:

(1)、aio_read--异步读

(2)、aio_write--异步写

(3)、aio_error--确定请求的状态

(4)、aio_return--获得异步操作的返回值

(5)、aio_suspend--挂起异步操作,知道异步请求完成为止

(6)、aio_cancel--取消异步请求

(7)、lio_listio--同时发起多个传输(一次系统调用可以启动大量的I/O操作)

4.2、使用信号作为AIO的通知

信号作为异步通知的机制在AIO中依然使用,为了使用信号,使用AIO的应用程序同样需要定义信号处理程序,在指定的信号被触发时,调用这个处理程序

4.3 使用回调函数作为AIO的通知

4.4 AIO与设备驱动

在内核中,每个I/O请求都对应一个kiocb结构体,其ki_filp成员只想对应的file指针,通过is_sync_kiocb判断某kiocb是否为同步I/O请求,如果是返回真,表示为异步I/O请求。

块设备和网络设备:本身是异步的

字符设备:必须明确应支持AIO(极少数是异步I/O操作)

 

 

 

 

 

 

原创粉丝点击