异步通知fasync与系统调用signal和sigaction函数配合使用
signal函数提供一个信号与信号处理函数的对应方式,每接收到这个信号就会调用相应的处理函数。
fasync则提供驱动程序与进程的联系。
应用层工作
signal(SIGIO, sig_handler);
调用signal函数,让指定的信号SIGIO与处理函数sig_handler对应。fcntl(fd, F_SET_OWNER, getpid());
指定一个进程作为文件的“属主(filp->owner)”,这样内核才知道信号要发给哪个进程。f_flags = fcntl(fd, F_GETFL);
fcntl(fd, F_SETFL, f_flags | FASYNC);
在设备文件中添加FASYNC标志,驱动中就会调用将要实现的test_fasync函数。
内核工作
把一个结构体struct fasync_struct添加到内核的异步查找队列头中。
这个结构体用来存放对应设备文件的信息(如fd, filp)并交给内核来管理。
一但收到信号,内核就会在这个所谓的异步队列头找到相应的文件(fd),并在filp->owner中找到对应的进程PID,并且调用对应的sig_handler。
驱动工作
定义结构体fasync_struct。
通过.fasync函数接口将结构体传给内核。
当设备可用时,调用函数kill_fasync发送信号SIGIO给内核。
当设备关闭时,将fasync_struct从异步队列中删除