`
yuexiaodong
  • 浏览: 70415 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

linux AIO详细总结(阻塞模型)

阅读更多

简介:Linux 异步 I/O 是 Linux 内核中提供的一个相当新的增强。它是 2.6 版本内核的一个标准特性,但是我们在 2.4 版本内核的补丁中也可以找到它。AIO 背后的基本思想是允许进程发起很多 I/O 操作,而不用阻塞或等待任何操作完成。

异步非阻塞 I/O 模型是一种处理与 I/O 重叠进行的模型。读请求会立即返回,说明 read 请求已经成功发起了。在后台完成读操作时,应用程序然后会执行其他处理操作。当 read 的响应到达时,就会产生一个信号或执行一个基于线程的回调函数来完成这次 I/O 处理过程。
linux AIO示意
在一个进程中为了执行多个 I/O 请求而对计算操作和 I/O 处理进行重叠处理的能力利用了处理速度与 I/O 速度之间的差异。当一个或多个 I/O 请求挂起时,CPU 可以执行其他任务;或者更为常见的是,在发起其他 I/O 的同时对已经完成的 I/O 进行操作。
       在异步非阻塞 I/O 中,我们可以同时发起多个传输操作。这需要每个传输操作都有惟一的上下文,这样我们才能在它们完成时区分到底是哪个传输操作完成了。在 AIO 中,这是一个 aiocb(AIO I/O Control Block)结构。这个结构包含了有关传输的所有信息,包括为数据准备的用户缓冲区。在产生 I/O (称为完成)通知时,aiocb 结构就被用来惟一标识所完成的 I/O 操作。这个 API 的展示显示了如何使用它。
表 1. AIO 接口 API
API 函数 说明
aio_read 请求异步读操作
aio_error 检查异步请求的状态
aio_return 获得完成的异步请求的返回状态
aio_write 请求异步写操作
aio_suspend 挂起调用进程,直到一个或多个异步请求已经完成(或失败)
aio_cancel 取消异步 I/O 请求
lio_listio 发起一系列 I/O 操作

详细见:http://www.ibm.com/developerworks/cn/linux/l-async/
阻塞模式下的IO过程如下:
int fd = open(const char *pathname, int flags, mode_t mode);
ssize_t pread(int fd, void *buf, size_t count, off_t offset);
ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset);
int close(int fd);
因为整个过程会等待read/write的返回,所以不需要任何额外的数据结构。但异步IO的思想是:应用程序不能阻塞在昂贵的系统调用上让CPU睡大觉,而是将IO操作抽象成一个个的任务单元提交给内核,内核完成IO任务后将结果放在应用程序可以取到的地方。这样在底层做I/O的这段时间内,CPU可以去干其他的计算任务。但异步的IO任务批量的提交和完成,必须有自身可描述的结构,最重要的两个就是iocb和io_event。
libaio中的structs
struct iocb {
void *data; /* Return in the io completion event */
unsigned key; /*r use in identifying io requests */
short aio_lio_opcode;
short aio_reqprio;
int aio_fildes;
union {
struct io_iocb_common c;
struct io_iocb_vector v;
struct io_iocb_poll poll;
struct io_iocb_sockaddr saddr;
} u;
};
struct io_iocb_common {
void *buf;
unsigned long nbytes;
long long offset;
unsigned flags;
unsigned resfd;
};
 iocb是提交IO任务时用到的,可以完整地描述一个IO请求:
data是留给用来自定义的指针:可以设置为IO完成后的callback函数;
aio_lio_opcode表示操作的类型:IO_CMD_PWRITE | IO_CMD_PREAD;
aio_fildes是要操作的文件:fd;
io_iocb_common中的buf, nbytes, offset分别记录的IO请求的mem buffer,大小和偏移。
struct io_event {
void *data;
struct iocb *obj;
unsigned long res;
unsigned long res2;
};
 io_event是用来描述返回结果的:
 
obj就是之前提交IO任务时的iocb;
 
res和res2来表示IO任务完成的状态。
 
AIO实现一般使用libaio进行在用户层实现,libaio提供了很多简易的操作API:
libaio提供的API有:io_setup, io_submit, io_getevents, io_destroy。
 
1. 建立IO任务
int io_setup (int maxevents, io_context_t *ctxp);
io_context_t对应内核中一个结构,为异步IO请求提供上下文环境。注意在setup前必须将io_context_t初始化为0。当然,这里也需要open需要操作的文件,注意设置O_DIRECT标志。
2.提交IO任务
long io_submit (aio_context_t ctx_id, long nr, struct iocb **iocbpp);
提交任务之前必须先填充iocb结构体,libaio提供的包装函数说明了需要完成的工作:
void io_prep_pread(struct iocb *iocb, int fd, void *buf, size_t count, long long offset)

{
memset(iocb, 0, sizeof(*iocb));
iocb->aio_fildes = fd;
iocb->aio_lio_opcode = IO_CMD_PREAD;
iocb->aio_reqprio = 0;
iocb->u.c.buf = buf;
iocb->u.c.nbytes = count;
iocb->u.c.offset = offset;
}

void io_prep_pwrite(struct iocb *iocb, int fd, void *buf, size_t count, long long offset)
{
memset(iocb, 0, sizeof(*iocb));
iocb->aio_fildes = fd;
iocb->aio_lio_opcode = IO_CMD_PWRITE;
iocb->aio_reqprio = 0;
iocb->u.c.buf = buf;
iocb->u.c.nbytes = count;
iocb->u.c.offset = offset;
}
 这里注意读写的buf都必须是按扇区对齐的,可以用posix_memalign来分配。
3.获取完成的IO
long io_getevents (aio_context_t ctx_id, long min_nr, long nr, struct io_event *events, struct timespec *timeout);
这里最重要的就是提供一个io_event数组给内核来copy完成的IO请求到这里,数组的大小是io_setup时指定的maxevents。
timeout是指等待IO完成的超时时间,设置为NULL表示一直等待所有到IO的完成。
4.销毁IO任务
int io_destroy (io_context_t ctx);
 
分享到:
评论

相关推荐

    linux_aio.zip_LINUX下开启AIO_aio glibc_aio 两种方式_linux aio_linux_aio

    在Linux操作系统中,异步I/O(Asynchronous Input/Output,简称AIO)是一种提高程序效率的方法,它允许程序在不等待I/O操作完成的情况下继续执行其他任务。本压缩包"linux_aio.zip"包含了关于如何在Linux下开启AIO...

    linux-aio:如何使用Linux AIO功能

    注意,Linux AIO现在包含在io_uring API中( , )。 以下说明对旧内核最为有用。介绍异步输入/输出(AIO)接口允许并行提交许多I / O请求,而每个请求没有线程的开销。 本文档的目的是解释如何使用Linux AIO接口,...

    linux异步IO aio

    ### Linux异步IO aio #### 引言 随着网络技术的发展和CPU性能的提升,传统的网络编程接口(如Unix套接字API)已逐渐无法满足高效处理大量数据的需求。当前的操作系统在网络接口方面存在局限性,尤其是在数据传输...

    幽默讲解linux的SocketIO模型.pdf

    总结起来,Linux的Socket I/O模型各有优劣,同步阻塞模型简单易用,但效率较低;同步非阻塞和I/O复用模型提高了效率,但需要处理复杂的回调逻辑;信号驱动I/O模型减少了轮询,但依赖于信号机制;异步I/O模型提供了...

    linux 5中 IO模型.pptx

    在Linux操作系统中,有五种主要的IO模型,分别是阻塞IO、非阻塞IO、IO多路复用、信号驱动IO和异步IO。这些模型决定了应用程序如何与硬件进行交互,以获取和处理输入/输出数据。以下是对这五种模型的详细解释: 1. ...

    网络IO模型 Linux环境下的network IO

    本主题将深入探讨几种主要的网络I/O模型,包括阻塞I/O、非阻塞I/O、I/O复用、信号驱动I/O以及异步I/O,并结合Linux内核机制进行详细分析。 1. **阻塞I/O模型** 在阻塞I/O模型中,当进程尝试读取或写入数据时,如果...

    linux 设备驱动中的阻塞与非阻塞 I/O

    《Linux设备驱动开发详解》这本书由宋宝华编写,详细阐述了Linux设备驱动的各个方面,包括I/O模型的选择和实现,是学习Linux驱动开发的宝贵参考资料。通过阅读本书,读者可以深入理解Linux内核的I/O机制,并掌握编写...

    linux内核详细解释

    Linux内核支持AIO(异步I/O)接口,用于非阻塞的数据传输。 9. 虚拟化:KVM(Kernel-based Virtual Machine)是Linux内核内置的虚拟化技术,它允许在一个物理系统上运行多个虚拟机,每个虚拟机都有自己的操作系统...

    使用异步AIO大大提高应用程序的性能.docx

    总结起来,POSIX AIO API是Linux中提升应用程序性能的重要工具,它通过异步非阻塞的方式处理I/O操作,实现了I/O操作与计算任务的并行处理,降低了延迟,提升了系统效率。理解和熟练运用AIO,可以为高性能和高并发的...

    浅谈Linux 网络 I/O 模型简介(图文)

    根据UNIX网络编程的分类,Linux提供了五种I/O模型,分别是阻塞I/O、非阻塞I/O、I/O复用模型、信号驱动I/O以及异步I/O。 1. **阻塞I/O模型**: 在这个模型中,进程调用如`recvfrom`这样的系统调用时,会一直等待...

    网络IO模型 Linux环境下的network IO 高清 目录 书签

    在Linux环境下,网络I/O(Input/Output)模型是系统进行网络通信的重要组成部分,它涉及到如何高效地处理来自网络的数据传输。本资源主要探讨的是在Linux操作系统中的网络I/O模型,包括其工作原理、常见类型以及优化...

    IO模型编程实例

    本篇文章将深入探讨四种主要的IO模型:阻塞IO、无阻塞IO、多路复用IO(也称为选择器或I/O多路复用)以及异步IO,结合源码分析来帮助理解它们的工作原理和应用。 首先,我们来看**阻塞IO**。在这种模型中,当一个...

    并发服务器的三种实现模型测试代码

    在Linux环境中,有三种主要的并发服务器模型:简单阻塞I/O(BIO)、多路复用I/O(如epoll)以及异步非阻塞I/O(AIO)。下面将详细介绍这三种模型,并探讨它们的优缺点和适用场景。 1. **简单阻塞I/O (BIO)** BIO是...

    linux异步IO.pdf

    传统上,Linux采用的最常见I/O模型是同步I/O,其中应用程序在发出请求后会阻塞,直至请求完成。然而,随着现代应用程序对性能和效率需求的提升,异步I/O作为一种先进的技术,为解决高并发场景下的I/O瓶颈提供了新...

    一文理解异步同步阻塞与费阻塞

    - **示例**: 例如,在Linux中,可以通过 `aio_read` 和 `aio_write` 函数实现异步I/O。 #### Nginx中的epoll, poll, select **select**, **poll**, 和 **epoll** 都属于I/O复用模型,用于同时监控多个文件描述符的...

    Linux_IO_program.rar_linux 输入 驱动

    在Linux中,有五种主要的I/O模型:同步阻塞I/O、同步非阻塞I/O、I/O多路复用(如select、poll和epoll)、信号驱动I/O以及异步I/O(AIO)。这些模型各自有不同的性能特性和应用场景,选择合适的I/O模型对于优化程序...

    linux下非阻塞IO程序源码.zip

    在Linux操作系统中,非阻塞I/O(Non-blocking I/O)是一种重要的编程模型,它用于处理高并发和低延迟的场景。与传统的阻塞I/O不同,非阻塞I/O在进行读写操作时,如果数据尚未准备好,不会挂起进程,而是立即返回一个...

    LINUX_PPT.rar_Linux IO_linux ppt

    在Linux中,I/O模型主要有五种:同步I/O、异步I/O、阻塞I/O、非阻塞I/O和I/O复用。其中,阻塞I/O是最常见的模型,当进行读写操作时,如果数据未准备好,进程会被挂起,直到数据准备完成。非阻塞I/O则允许进程在数据...

Global site tag (gtag.js) - Google Analytics