异步通知:一旦设备就绪,就主动通知应用程序。比较准确的称谓是“信号驱动的异步I/O”
阻塞、非阻塞,异步通知本身没有优劣,根据不同的应用场景合理选择。
关于信号的接收处理在《进程通信笔记》中已经学习过。
因为sigaction函数是一个比signal函数更新,更健壮的信号接口,所以采用此接口。
异步通知关心以下几件事:
应用层
1.信号和信号处理函数
2.启动异步信号机制(FASYNC)
驱动层
3.添加对异步(FASYNC)的支持
4.资源可获取时,激发相应的信号
异步通知使用步骤
应用层
a.调用sigaction函数, 绑定信号与信号处理函数
struct sigaction act;
act.sa_handler=input_handler;
sigemptyset(&act.sa_mask);
axt.sa_flags=0;
sigaction(SIGIO,&act,0);
b.设置进程的拥有者与打开的设备相同。
fcntl(fd,F_SETOWN,getpid());
c.设置文件状态,支持FASYNC
oflags=fcntl(fd,F_GETFL);
fcntl(fd,F_SETFL,oflags | FASYNC);
驱动层
d.在设备结构体中加入fasync_struct结构体
{ …
struct fasync_struct *async_queue;
…}
e.增加对FASYNC标志支持的机制
static int xxx_fasync(int fd,struct file *filp,int mode)
{
struct xxx_dev *dev = filp->private_data;
return fasync_helper(fd,filp,mode,&dev->async_queue);
}
f.文件操作函数中,设备资源可获取时,释放SIGIO信号
if (dev->async_queue)
kill_fasync(&dev->async_queue, SIGIO, POLL_IN);
POLL_IN,为可读
POLL_OUT,为可写
g.文件关闭时,将文件从异步通知的列表中删除。
xxx_fasync(-1,filp,0);