内核中与驱动相关的内存操作之十六(异步I/O)
来源:互联网 发布:巴西农业部数据 mapa 编辑:程序博客网 时间:2024/05/27 10:42
1.异步IO简介:
Linux 异步 I/O 是Linux 2.6 中的一个标准特性,其本质思想就是进程发出数据传输请求之后,进程不会被阻塞,也不用等待任何操作完成,进程可以在数据传输的时候继续执行其他的操作.相对于同步访问文件的方式来说,异步访问文件的方式可以提高应用程序的效率,并且提高系统资源利用率.直接 I/O 经常会和异步访问文件的方式结合在一起使用.
如下:
2.内核中关于异步IO的API:
实际上,异步IO在驱动中很少会涉及.它也属于fpos中的一个成员.如下:
ssize_t (*aio_read) (struct kiocb *iocb, char *buffer,size_t count, loff_t offset);ssize_t (*aio_write) (struct kiocb *iocb, const char *buffer,size_t count, loff_t offset);int (*aio_fsync) (struct kiocb *iocb, int datasync);aio_fsync 操作只对文件系统代码感兴趣, 因此我们在此不必讨论它. 其他 2 个, aio_read 和 aio_write, 看起来非常象常规的 read 和 write 方法, 但是有几个例外. 一个是 offset 参数由值传递; 异步操作从不改变文件位置, 因此没有理由传一个指针给它.
这里比较核心的参数是iocb,它是由内核创建、传递的,专门用于异步IO操作的.
异步IO状态查询:
int is_sync_kiocb(struct kiocb *iocb);如果这个函数返回一个非零值, 你的驱动必须同步执行这个操作.
完成一个异步IO操作:
int aio_complete(struct kiocb *iocb, long res, long res2);iocb 是起初传递给你的同一个 IOCB,并且 res 是这个操作的通常的结果状态.res2 是将被返回给用户空间的第2个结果码;大部分的异步 I/O 实现作为 0 传递 res2. 一旦你调用 aio_complete,你不应当再碰 IOCB 或者用户缓冲.
3.示例模板:
下面的示例模板来自LDD3.
static ssize_t scullp_aio_read(struct kiocb *iocb, char *buf, size_t count, loff_t pos){ return scullp_defer_op(0, iocb, buf, count, pos);}static ssize_t scullp_aio_write(struct kiocb *iocb, const char *buf, size_t count, loff_t pos){ return scullp_defer_op(1, iocb, (char *) buf, count, pos);}其中,scullp_aio_read()和scullp_aio_write()分别对应用户空间的异步读写的系统调用.两函数只调用了scullp_defer_op()函数:
struct async_work{ struct kiocb *iocb; int result; struct work_struct work;};static int scullp_defer_op(int write, struct kiocb *iocb, char *buf, size_t count, loff_t pos){ struct async_work *stuff; int result; /* Copy now while we can access the buffer */ if (write) result = scullp_write(iocb->ki_filp, buf, count, &pos); else result = scullp_read(iocb->ki_filp, buf, count, &pos); /* If this is a synchronous IOCB, we return our status now. */ if (is_sync_kiocb(iocb)) return result; /* Otherwise defer the completion for a few milliseconds. */ stuff = kmalloc (sizeof (*stuff), GFP_KERNEL); if (stuff == NULL) return result; /* No memory, just complete now */ stuff->iocb = iocb; stuff->result = result; INIT_WORK(&stuff->work, scullp_do_deferred_op, stuff); schedule_delayed_work(&stuff->work, HZ/100); return -EIOCBQUEUED;}注意到上述对iocb进行了状态的轮询,见上述语句:
if (is_sync_kiocb(iocb)) return result;一个异步IO的完成在等待队列里面:
static void scullp_do_deferred_op(void *p) { struct async_work *stuff = (struct async_work *) p; aio_complete(stuff->iocb, stuff->result, 0); kfree(stuff); }
0 0
- 内核中与驱动相关的内存操作之十六(异步I/O)
- 内核中与驱动相关的内存操作之十四(直接I/O)
- 内核中与驱动相关的内存操作之十五(标准I/O)
- 内核中与驱动相关的内存操作之八(面向页的内存分配)
- 内核中与驱动相关的内存操作之三(内存模型)
- 内核中与驱动相关的内存操作之十(内存屏障)
- 内核中与驱动相关的内存操作之十一(IO内存)
- 内核中与驱动相关的内存操作之一(MMU)
- 内核中与驱动相关的内存操作之二(cache)
- 内核中与驱动相关的内存操作之四(常用结构体)
- 内核中与驱动相关的内存操作之五(kmalloc)
- 内核中与驱动相关的内存操作之六(vmalloc)
- 内核中与驱动相关的内存操作之七(slab)
- 内核中与驱动相关的内存操作之九(重映射)
- 内核中与驱动相关的内存操作之十二(mmap)
- 内核中与驱动相关的内存操作之十三(/dev/mem)
- 内核中与驱动相关的内存操作之十七(DMA)
- 内核驱动之I/O内存访问
- a:link,a:visited,a:hover,a:active
- java注解demo
- Unity 3D 开发技巧分享&工具推荐
- Java Web 监听器 (计算在线人数)
- 使用Qt实现MDI风格的主窗体
- 内核中与驱动相关的内存操作之十六(异步I/O)
- MySQL常用到的一些phpmyadmin配置总结
- 指针常量和常量指针
- 点到线段的垂直距离
- webview出错
- 射线和三角形相交检测
- java正则表达式基础
- Ubuntu切换到ROOT账户 (copied)
- 使用线程互斥量,实现进程的PV操作