fasync异步通知
更多信息请看:http://blog.csdn.net/mirkerson/article/details/7443907
http://hi.baidu.com/decload/item/713bffa94c17c8991410737e
这里讲的异步通知,是指设备数据就绪了(可读或可写),驱动可以发送一个信号给进程(该文件的属主进程)。通过使用异步通知,无论何时数据可用,应用程序可以接收到一个信号并且不需要让自己去轮询。
异步通知的功能需要应用和驱动完成一些步骤。
⒈ 应用程序应做的工作
⑴ 注册信号处理函数。
通过signal 或sigaction()实现。
⑵ 使进程成为该文件的的属主进程。
通过fcntl 的F_SETOWN命令来实现。如fcntl(fd, F_SETOWN,getpid());
⑶ 启用异步通知功能。
通过fcntl 的F_SETFL命令设置FASYNC标记。
例如,
下面的用户程序中的代码行使能了异步的通知到当前进程, 给 stdin输入文件:
---------------------------------------------------------------------
signal(SIGIO, &input_handler); /* dummy sample; sigaction() is better*/
fcntl(STDIN_FILENO, F_SETOWN, getpid());
oflags = fcntl(STDIN_FILENO, F_GETFL);
fcntl(STDIN_FILENO, F_SETFL, oflags | FASYNC);
---------------------------------------------------------------------
在内核里异步通知是通过,异步通知队列struct fasync_struct来实现的。在这里,我们只需要用到内核提供的两个有关异步通知队列的函数就可以了。fasync_helper和
kill_fasync。
fasync_helper用于把文件指针加到(或移除,当参数on =
0)异步通知队列
kill_fasync用于发送信号给应用程序。
---------------------------------------------------------------------
fs/fcntl.c
int fasync_helper(int fd, struct file * filp, int on, struct fasync_struct**fapp)
{
if (!on)
returnfasync_remove_entry(filp, fapp);
return fasync_add_entry(fd, filp,fapp);
}
---------------------------------------------------------------------
---------------------------------------------------------------------
fs/fcntl.c
void kill_fasync(struct fasync_struct **fp, int sig, int band)
{
/* First a quick test withoutlocking: usually
* the list is empty.
*/
if (*fp) {
rcu_read_lock();
kill_fasync_rcu(rcu_dereference(*fp),sig, band);
rcu_read_unlock();
}
}
---------------------------------------------------------------------
具体的字符设备驱动通过下面这几个步骤来实现:
⑴ 实现structfile_operations的.fasync函数。
这个函数,会在应用程序里,设置/删除FASYNC文件标记时会调用。该函数指针的原型为:
int (*fasync)(intfd, struct file *filp, int mode) ;
在函数实现时,我们只需要调用:
int fasync_helper(int fd, struct file *filp, int on, struct fasync_struct **fapp) ;
⑵在数据就绪时,调用kill_fasync通知应用程序
⑶ 在用户关闭文件(在realease函数里)时,把该文件指针从异步通知队列里删除。同样也是调用fasync_helper。
fasync简介
应用层中启用异步通知机制
驱动中需要实现的异步通知
3.1 异步通知内核实现
3.2 fasync_struct结构体
3.3 内核中我们的工作
3.4 其余的工作