C中异步IO浅析之二:基于libaio的异步IO

简介:

在实际的文件系统等高并发度的场景中,用得更多的是异步IO模式还是基于libaio。下面简要介绍基于libaio的实现。

 

1 安装依赖头文件和库

 

由于libaio不是centos原生的支持,需要手动安装开发库:

 

[root@localhost test]# yum install libaio.x86_64 libaio-devel.x86_64

 

2 理解主要的数据结构和API

 

主要的内容在:/usr/include/libaio.h



wKiom1nO8-uguLUDAAHjNd3_Ydk992.png

显然从上面的iocb数据结构能看出:它支持单个的io操作(io_iocb_common),也支持成批的IO处理(io_iocb_vector),还支持基于polling 模式。

 

为了便于实际调用,避免对内部数据结构初始化的麻烦,它还封装好了多个常用的inline函数,这些inline函数基本上可以理解成宏:

 

static inline int io_fsync(io_context_t ctx, struct iocb *iocb, io_callback_t cb, int fd)

{

    io_prep_fsync(iocb, fd);

    io_set_callback(iocb, cb);

    return io_submit(ctx, 1, &iocb);

}

 

static inline void io_prep_fdsync(struct iocb *iocb, int fd)

{

    memset(iocb, 0, sizeof(*iocb));

    iocb->aio_fildes = fd;

    iocb->aio_lio_opcode = IO_CMD_FDSYNC;

    iocb->aio_reqprio = 0;

}

 

static inline int io_fdsync(io_context_t ctx, struct iocb *iocb, io_callback_t cb, int fd)

{

    io_prep_fdsync(iocb, fd);

    io_set_callback(iocb, cb);

    return io_submit(ctx, 1, &iocb);

}

 

不同于上一篇博客中提到的那种异步IO通过信号机制实现异步,libaio主要用event 来实现异步:一个IO初始化的时候对应一个io event, 每完成一个IO就产生一个event, 因此IO 请求提交之后,随时检查返回的io event的数量,就知道哪些IO已经完成。

 

static inline void io_set_eventfd(struct iocb *iocb, int eventfd)

{

    iocb->u.c.flags |= (1 << 0) /* IOCB_FLAG_RESFD */;

    iocb->u.c.resfd = eventfd;

}

 

3. 注意事项


3.1  aio context 数据结构在调用之前必须清0;

 DESCRIPTION

       The  io_setup()  system  call  creates an asynchronous I/O context suitable for concurrently processing nr_events operations.  The ctx_idp argument must not

       point to an AIO context that already exists, and must be initialized to 0 prior to the call.  On successful creation of the AIO context, *ctx_idp is  filled

       in with the resulting handle.

 

 

3.2  aio context system call : io_submit/io_setup 系统调用等不能直接使用,需要调用wrapper().

 

 Note that the libaio wrapper function uses a different type (io_context_t *) for the ctx_idp argument.  Note also that the libaio wrapper  does  not  follow

       the  usual C library conventions for indicating errors: on error it returns a negated error number (the negative of one of the values listed in ERRORS).  If

       the system call is invoked via syscall(2), then the return value follows the usual conventions for indicating an error: -1, with errno set to  a  (positive)

       value that indicates the error.

 

3.3 注意数据结构的区别

aio_context_t 只在libaio.h 中有定义;

而io_context_t 只是在linux/aio_abi.h 和 aio.h中有定义。

 

4. 如何实现事件传递和异步

 

实际文件系统中常见的用法:

memset(&myctx, 0, sizeof(myctx)) 初始化有ioctx;

io_queue_init(AIO_MAXIO, &myctx); 第一个参数指定了IO数目吧

 

io_prep_pread()/ io_prep_pwrite()

io_set_callback(io, callbak); //  设置IO完成之后的回调函数

 

io_submit()提交一组IO 请求;

io_getevents()得到已经执行完的IO数目及其状态。

 

io_run_queue()

io_wait_queue()

 

5. 编译

不能再像自带的aio库一样依赖librt了,否则编译过程当会出现类似下面的错误:

[root@localhost test]# gcc -o libaio_test libaio_test.c  -lrt

/tmp/ccXHzl0H.o: In function `main':

libaio_test.c:(.text+0x62): undefined reference to `io_setup'

libaio_test.c:(.text+0x8f): undefined reference to `io_prep_pwrite'

libaio_test.c:(.text+0xae): undefined reference to `io_fsync'

collect2: error: ld returned 1 exit status

 

而应该用libaio:

gcc -o libaio_test libaio_test.c  -laio (库在/lib64下面:./lib64/libaio.so.1) 连接到linux的libaio.so库。

 

 

6. 参考链接

http://blog.csdn.net/ixidof/article/details/51211508

http://blog.csdn.net/zhaofuguang/article/details/12853881

http://blog.csdn.net/zhaofuguang/article/details/12853883

 

 

 

 












本文转自存储之厨51CTO博客,原文链接: http://blog.51cto.com/xiamachao/1969902,如需转载请自行联系原作者



相关文章
|
27天前
|
算法 数据处理 Python
Python并发编程:解密异步IO与多线程
本文将深入探讨Python中的并发编程技术,重点介绍异步IO和多线程两种常见的并发模型。通过对比它们的特点、适用场景和实现方式,帮助读者更好地理解并发编程的核心概念,并掌握在不同场景下选择合适的并发模型的方法。
|
6月前
|
数据采集 并行计算 Java
【文末送书】Python高并发编程:探索异步IO和多线程并发
【文末送书】Python高并发编程:探索异步IO和多线程并发
128 0
|
2天前
|
人工智能 算法 调度
uvloop,一个强大的 Python 异步IO编程库!
uvloop,一个强大的 Python 异步IO编程库!
10 2
|
3天前
|
API 调度 开发者
Python中的并发编程:使用asyncio库实现异步IO
传统的Python编程模式中,使用多线程或多进程实现并发操作可能存在性能瓶颈和复杂性问题。而随着Python 3.5引入的asyncio库,开发者可以利用异步IO来更高效地处理并发任务。本文将介绍如何利用asyncio库实现异步IO,提升Python程序的并发性能。
|
1月前
|
调度 数据库 Python
Python中的并发编程:使用asyncio库实现异步IO
传统的Python程序在面对IO密集型任务时,往往会遇到性能瓶颈。本文将介绍如何利用Python中的asyncio库,通过异步IO的方式来提升程序的效率和性能,让你的Python程序能够更好地处理并发任务。
|
5月前
|
存储 网络协议 Linux
2.10 高性能异步IO机制:io_uring
2.10 高性能异步IO机制:io_uring
317 0
|
2月前
|
程序员 调度 云计算
Python并发编程的未来趋势:协程、异步IO与多进程的融合
Python并发编程的未来趋势:协程、异步IO与多进程的融合
|
2月前
|
数据采集 Python
Python多线程与异步IO的对比:何时选择哪种并发模型
Python多线程与异步IO的对比:何时选择哪种并发模型
|
2月前
|
开发者 Python
Python中的并发编程与异步IO
在当今快节奏的互联网时代,如何提高程序的执行效率成为了开发者们关注的焦点。本文将探讨Python中的并发编程与异步IO技术,介绍其原理、应用场景以及优缺点,帮助读者更好地理解和运用这些技术来提升程序性能。