Linux异步通知
异步通知
作用:一旦设备就绪, 则主动通知应用程序, 这样应用程序根本就不需要查询设备状态, 这一点非常类似于硬件上“中断”的概念, 比较准确的称谓是“信号驱动的异步I/O”。
阻塞I/O意味着一直等待设备可访问后再访问, 非阻塞I/O中使用poll() 意味着查询设备是否可访问, 而异步通知则意味着设备通知用户自身可访问, 之后用户再进行I/O处理。
#include <signal.h>
void (*signal (int signo, void (func)(int)))(int);
//signo是设置的信号,signal会捕捉signo,并触发func
除了SIGSTOP和SIGKILL两个信号外, 进程能够忽略或捕获其他的全部信号
sigaction函数
可用于改变进程接收到特定信号后的行为, 它的原型为:
int sigaction(int signum,const struct sigaction *act,struct sigaction *oldact));
//signum捕获的信号,act:新的处理行为 oldact:原有的处理行为
信号的释放
在设备驱动和应用程序的异步通知交互中, 仅仅在应用程序端捕获信号是不够的, 因为信号的源头在设备驱动端。 因此, 应该在合适的时机让设备驱动释放信号
为了使设备支持异步通知机制, 驱动程序中涉及3项工作。
1) 支持F_SETOWN命令, 能在这个控制命令处理中设置filp->f_owner为对应进程ID。 不过此项工作已由内核完成, 设备驱动无须处理。
2) 支持F_SETFL命令的处理, 每当FASYNC标志改变时, 驱动程序中的fasync() 函数将得以执行。因此, 驱动中应该实现fasync() 函数。
3) 在设备资源可获得时, 调用kill_fasync() 函数激发相应的信号。
设备驱动异步通知编程
1) 处理FASYNC标志变更的函数。
int fasync_helper(int fd, struct file *filp, int mode, struct fasync_struct **fa);
2) 释放信号用的函数。
void kill_fasync(struct fasync_struct **fa, int sig, int band);
3)fasync_struct结构体
异步I/O
AIO有多种实现, 其中一种实现是在用户空间的glibc库中实现的, 它本质上是借用了多线程模型, 用开启新的线程以同步的方法来做I/O, 新的AIO辅助线程与发起AIO的线程以
pthread_cond_signal() 的形式进行线程间的同步。
//异步读操作
int aio_read( struct aiocb *aiocbp );
//异步写操作
int aio_write( struct aiocb *aiocbp );
//确定请求状态
int aio_error( struct aiocb *aiocbp );
ssize_t aio_return( struct aiocb *aiocbp );
//阻塞调用进程, 直到异步请求完成为止
int aio_suspend( const struct aiocb *const cblist[],int n, const struct timespec *timeout);
//允许用户取消对某个文件描述符执行的一个或所有I/O请求
int aio_cancel(int fd, struct aiocb *aiocbp);
lio_listio()
同时发起多个AIO传输,使得用户可以在一个系统调用中启动大量的I/O操作
int lio_listio( int mode, struct aiocb *list[], int nent, struct sigevent *sig );
posted on 2022-08-13 16:15 DylanYeung 阅读(85) 评论(0) 编辑 收藏 举报