dylanin1999

导航

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  阅读(69)  评论(0编辑  收藏  举报