异步通知:一旦设备就绪,则主动通知应用程序,这样应用程序根本不需要查询设备状态,这一点非常类似于硬件上的“中断”的概念,比较准确的称谓是“信号驱动的异步I/O
//启动信号驱动机制
signal(SIGIO, input_handler);//让input_handler()处理SIGIO信号
fcntl(fd, F_SETOWN, getpid());//设置本进程为STDIN_FILENO文件的拥有者,让内核知道将信号发给本进程
oflags = fcntl(fd, F_GETFL);//下面两句:设置FASYNC标志,启动异步通知标志
fcntl(fd, F_SETFL, oflags | FASYNC);
设备驱动中异步通知编程比较简单,主要用到一项数据结构和两个函数
数据结构:
struct xxx_dev
{
Struct cdev cdev;
……
Struct fasync_struct *async_queue;
}
Int fasync_helper(int fd, struct file *filp, int mode, struct fasync_struct **fa);
Void kill_fasync(struct fasync_struct **fa, int sig, int band);
static int globalfifo_fasync(int fd, struct file *filp, int mode)
{
struct globalfifo_dev *dev = filp->private_data;
return fasync_helper(fd, filp, mode, &dev->async_queue);
}
static ssize_t globalfifo_write(struct file *filp, const char __user *buf,
size_t count, loff_t *ppos)
{
struct globalfifo_dev *dev = filp->private_data; //获得设备结构体指针
……
if (dev->async_queue)
kill_fasync(&dev->async_queue, SIGIO, POLL_IN);
ret = count;
}
int globalfifo_release(struct inode *inode, struct file *filp)
{
globalfifo_fasync( - 1, filp, 0);
return 0;
}
AIO基本思想是允许进程发起很多I/O操作,而不用阻塞或等待任何操作完成
异步IO和标准IO之间的另一个区别是不能立即访问这个函数的返回状态,因为并没有阻塞在read()调用上。在标准的read()调用中,返回状态是在该函数返回时提供的,但是在异步IO中,我们要使用aio_return()函数,只有在aio_error()调用请求已经完成之后,才会调用aio_reaturn()
回调:下层对上层(如内核对应用)的调用