linux_aio

所属分类:Linux/Unix编程
开发工具:C/C++
文件大小:4KB
下载次数:7
上传日期:2013-09-27 09:12:32
上 传 者shellhand
说明:  Linux 下实现异步IO有两种方式,一种是调用glibc的aio,本代码是在学习Unix环境高级编程时测试的glibc的aio函数,有详细的README说明文档和注释。
(asynchronous io using linux glibc aio library。)

文件列表:
v1 (0, 2013-09-27)
v1\lab2.c (3106, 2013-09-27)
v1\Makefile (171, 2013-05-05)
v1\testfile (13087, 2013-05-10)

运行环境:Ubuntu 11.10 运行方法:make之后./lab2 实现: 调用了glibc中的aio.h,是gnu的aio机制。 通过get_file_size来获取文件大小 O_RDONLY方式打开文件,得到fd 注册SIGIO处理函数aio_completion_handler 使用aio库提供的aiocb结构填充异步io信息 调用异步io函数,aio_read main函数sleep SIGIO处理函数捕捉到SIGIO信号,返回并告知main函数结束 结束 上述实现方式有缺陷,在deadline之前发现了程序有bug。这是因为之前的程序并没有读完文件,只是读完了BUFFER, 所以还要加入一个循环,循环都满buffer知道读完文件。具体的实现方式补充如下: filesize/buffersize得到需要读取的次数,timesToRead 每收到一次SIGIO,timesRead++, 判断timesRead是否>timesToRead,如果不满足,则继续读取,同时注意文件偏移量+Buffersize 如果到达读取的次数,则返回。 分析总结: 虽然Lab2最终提交的代码不多,但这个lab花费的功夫可比lab1多好多。 首先是异步IO的实现问题,现在总结起来一共有三种方式(其实是两种) 第一种就是我的代码中使用的glibc版本的aio,这个版本其实是饱受非议的,因为它使用的是多线程的方式来异步工作的,也就是这个版本是通过read时开启一个新的线程来读取,这也就带来了多线程的坏处,会额外地占用CPU资源,对线程的创建、销毁、调度等都需要CPU开销,并且调用者线程和异步处理线程之间也存在线程间通信的开销。但这样做的优点是IO请求的提交都由异步线程处理,调用者线程可以更快的响应其他事情,如果CPU资源充足,这种实现是不错的。而且glibc版本支持非direct-io,可以利用内核提供的page cache来提高效率。 第二种是Linux内核的原生异步IO,这在2.4版本以上都有,2.6已经固定为内核特性。这种异步IO实际上是利用了CPU和IO设备可以异步工作的特性,IO请求提交的过程主要还是在调用者线程上同步完成的,请求提交后由于CPU与IO设备可以并行工作,所以调用流程可以返回,调用者可以继续做其他事情,这种方法不会额外的占用CPU资源,而且如果是多个IO请求,因为所有请求都倍提交给了IO调度器,IO调度器可以使用优化算法来优化服务,可能取得更好的效果。但是这种方法只支持direct-io,cache只能靠用户程序来实现。 还有一种方法也就是课本14.6.2中提到的BSD的异步IO,也就是在read时设置O_ASYNC文件状态标志,但是这仅对指向终端和网络的描述符执行,也就是只能对STDIN/STDOUT和Socket进行,一开始我没有看到这句话,结果花费了好长时间都无法捕捉信号,哎。。。。。。。 最后我选择了方法一,也就是glibc的异步IO。 结论: 异步的方式不必等待IO的执行,使得程序可以按照继续处理,IO操作和应用程序可以同时运行,提高了系统性能,提高了IO流量。但是,目前绝大多数异步都是多线程+同步IO来实现的,真正的异步IO目前应用较少,不过在数据库、设备驱动方面异步IO有较大的应用前景。 这次Lab收获还是颇多的,特别是在课堂上没有讲的情况下熟悉了BLOCKING、NON-BLOCKING、SYNCHRONOUS、ASYNCHRONOUS这几种IO模型(鉴于都是在网上看到的,这里就不贴出来了),对以后的学习会有很大的帮助。

近期下载者

相关文件


收藏者