linux异步IO浅析

本文深入探讨了Linux下的两种异步IO实现:glibc版本和Linux内核版本。glibc版本通过异步处理线程实现,而Linux内核版本则使用io_context_t和io_event结构,通过内核直接在用户空间分配内存来处理IO请求,减少了系统调用的开销。两种实现各有优劣,适用于不同的场景和资源需求。
摘要由CSDN通过智能技术生成

知道异步IO已经很久了,但是直到最近,才真正用它来解决一下实际问题(在一个CPU密集型的应用中,有一些需要处理的数据可能放在磁盘上。预先知道这些数据的位置,所以预先发起异步IO读请求。等到真正需要用到这些数据的时候,再等待异步IO完成。使用了异步IO,在发起IO请求到实际使用数据这段时间内,程序还可以继续做其他事情)。
假此机会,也顺便研究了一下linux下的异步IO的实现。

linux下主要有两套异步IO,一套是由glibc实现的(以下称之为glibc版本)、一套是由linux内核实现,并由libaio来封装调用接口(以下称之为linux版本)。


glibc版本

接口
glibc版本主要包含如下接口:
int aio_read(struct aiocb *aiocbp); 
int aio_write(struct aiocb *aiocbp);
int aio_cancel(int fildes, struct aiocb *aiocbp);
int aio_error(const struct aiocb *aiocbp);       
ssize_t aio_return(struct aiocb *aiocbp);        
int aio_suspend(const struct aiocb * const list[], int nent, const struct timespec *timeout);

其中,struct aiocb主要包含以下字段:
int               aio_fildes;       
void *            aio_buf;          
__off64_t         aio_offset;       
size_t            aio_nbytes;       
int               aio_reqprio;      
struct sigevent   aio_sigevent;     

 

实现
glibc的aio实现是比较通俗易懂的:
1、异步请求被提交到request_queue中;
2、request_queue实际上是一个表结构,"行"是fd、"列"是具体的请求。也就是说,同一个fd的请求会被组织在一起;
3、异步请求有优先级概念,属于同一个fd的请求会按优先级排序,并且最终被按优先级顺序处理;
4、随着异步请求的提交,一些异步处理线程被动态创建。这些线程要做的事情就是从request_queue中取出请求,然后处理之;
5、为避免异步处理线程之间的竞争,同一个fd所对应的请求只由一个线程来处理;
6、异步处理线程同步地处理每一个请求,处理完成后在对应的aiocb中填充结果,然后触发可能的信号通知或回调函数(回调函数是需要创建新线程来调用的);
7、异步处理线程在完成某个fd的所有请求后,进入闲置状态;
8、异步处理线程在闲置状态时,如果request_queue中有新的fd加入,则重新投入工作,去处理这个新fd的请求(新fd和它上一次处理的fd可以不是同一个);
9、异步处理线程处于闲置状态一段时间后(没有新的请求),则会自动退出。等到再有新的请求时,再去动态创建;

看起来,换作是我们,要在用户态实现一个异步IO,似乎大概也会设计成类似的样子……


linux版本

接口
下面再来看看linux版本的异步IO。它主要包含如下系统调用接口:
int io_setup(int maxevents, io_context_t *ctxp); 
int io_destroy(io_cont

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值