相较于同步IO,异步IO请求发出后,应用程序不用阻塞,可以继续执行后面的业务流程,因此能够极大提高系统并发度和吞吐率。这也是为何许多SAN服务后端数据落盘常常采用异步IO读写的原因。
C语言中提供了两套实现异步IO的方法,根据个人的理解,可以分为原生的AIO_ABI方法和集成的libaio方法。这篇主要介绍原生的异步IO的使用方法。
1. 头文件
和原生异步IO操作相关的函数对应的头文件包括:
/usr/include/linux/aio_abi.h:
里面的内容如下:
此外,还有 /usr/include/aio.h,里面既包括相应的数据结构的定义:
还包括了基本的aio操作:
2. 实现方法
基于上面的库的异步IO的实现有两种方式,示例代码分别如下:
mode 1: base don sleep method
上面这种方式在提交异步写请求之后,休眠一段时间,让后台完成IO请求。只要等待时间足够,IO一般能够完成。但本质上就变成同步的了,而且无法确保IO一定完成,因此,不建议用。
mode 2: based on signal mechanism 示例代码如下:
这种基于aio_xxx 的异步实现,需要通过无名信号量signal机制来判断是否IO完成。上面首先注册一个信号响应函数aioSigHandler, 接着设置异步完成之后产生指定的信号,并且把改信号和信号响应函数通过都注册到mycb的信号事件结构中去。
这样借助signal 通知的机制,就能判断异步IO是否完成,设置可以定制异步完成之后的处理函数。
3. 编译方式
需要链接动态库librt.so,可以参考下面的makefile
[[email protected] test]# cat makefile
dest=async_io
dest: async_io.c
gcc -o async_io async_io.c -lrt