相较于同步IO,异步IO请求发出后应用程序不用阻塞可以继续执行后面的业务流程因此能够极大提高系统并发度和吞吐率这也是为何许多SAN服务后端数据落盘常常采用异步IO读写的原因

 

C语言中提供了两套实现异步IO的方法根据个人的理解可以分为原生的AIO_ABI方法和集成的libaio方法这篇主要介绍原生的异步IO的使用方法

 

1. 头文件

和原生异步IO操作相关的函数对应的头文件包括

 

/usr/include/linux/aio_abi.h:

 

里面的内容如下


wKiom1nN6ACy0mslAAB7aiPfV6U966.png

 

 

此外还有 /usr/include/aio.h,里面既包括相应的数据结构的定义


wKioL1nN59GgV10SAABW5BBH-jw876.png

 


 

wKioL1nN5-zz-MK9AAB7aiPfV6U583.png 

 

还包括了基本的aio操作

 

wKioL1nN6Aqzm3qgAADif1cq7M4166.png

 

 

2. 实现方法

 

基于上面的库的异步IO的实现有两种方式示例代码分别如下

 

mode 1: base don sleep method

 

wKioL1nN6Hah-6EZAAAN_cFxnUw077.png

 

上面这种方式在提交异步写请求之后休眠一段时间让后台完成IO请求只要等待时间足够,IO一般能够完成但本质上就变成同步的了而且无法确保IO一定完成因此不建议用

 

mode 2: based on signal mechanism 示例代码如下

 

 

wKioL1nN6Bnj1fZ3AAAzK1IrXKo031.png

 

这种基于aio_xxx 的异步实现需要通过无名信号量signal机制来判断是否IO完成上面首先注册一个信号响应函数aioSigHandler, 接着设置异步完成之后产生指定的信号并且把改信号和信号响应函数通过都注册到mycb的信号事件结构中去

 

wKiom1nN6Nrz0HoKAABfBEOSPKA362.png

 

这样借助signal 通知的机制就能判断异步IO是否完成设置可以定制异步完成之后的处理函数

 

 

3. 编译方式

需要链接动态库librt.so,可以参考下面的makefile

[root@localhost test]# cat makefile

dest=async_io

 

dest: async_io.c

        gcc -o async_io async_io.c -lrt