目录

什么是异步 IO?

Linux 原生 AIO 原理

Linux 原生 AIO 使用


什么是异步 IO?


异步 IO:当应用程序发起一个 IO 操作后,调用者不能立刻得到结果,而是在内核完成 IO 操作后,通过信号或回调来通知调用者。

异步 IO 与同步 IO 的区别如 图1 所示:

从上图可知,同步 IO 必须等待内核把 IO 操作处理完成后才返回。而异步 IO 不必等待 IO 操作完成,而是向内核发起一个 IO 操作就立刻返回,当内核完成 IO 操作后,会通过信号的方式通知应用程序。

Linux 原生 AIO 原理


Linux Native AIO 是 Linux 支持的原生 AIO,为什么要加原生这个词呢?因为Linux存在很多第三方的异步 IO 库,如 libeioglibc AIO。所以为了加以区别,Linux 的内核提供的异步 IO 就称为原生异步 IO。

很多第三方的异步 IO 库都不是真正的异步 IO,而是使用多线程来模拟异步 IO,如 libeio 就是使用多线程来模拟异步 IO 的。

本文主要介绍 Linux 原生 AIO 的原理和使用,所以不会对其他第三方的异步 IO 库进行分析,下面我们先来介绍 Linux 原生 AIO 的原理。

如 图2 所示:

Linux 原生 AIO 处理流程:

  • 当应用程序调用 io_submit 系统调用发起一个异步 IO 操作后,会向内核的 IO 任务队列中添加一个 IO 任务,并且返回成功。

  • 内核会在后台处理 IO 任务队列中的 IO 任务,然后把处理结果存储在 IO 任务中。

  • 应用程序可以调用 io_getevents 系统调用来获取异步 IO 的处理结果,如果 IO 操作还没完成,那么返回失败信息,否则会返回 IO 处理结果。

从上面的流程可以看出,Linux 的异步 IO 操作主要由两个步骤组成:

  • 1) 调用 io_submit 函数发起一个异步 IO 操作。

  • 2) 调用 io_getevents 函数获取异步 IO 的结果。

下面我们主要分析,Linux 内核是怎么实现异步 IO 的。

Linux 原生 AIO 使用


在介绍 Linux 原生 AIO 的实现之前,先通过一个简单的例子来介绍其使用过程:

#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include <fcntl.h>
//#include <libaio.h>
#include <sys/stat.h>#include <linux/aio_abi.h>          /* Defines needed types *//*
gcc io_submit.c -laio*/int main()
{unsigned nr_events = 10;aio_context_t ctx_idp;
//    struct iocb _iocb[1];memset(ctx_idp, 0, sizeof(aio_context_t));int ret;int fd;char *buf;ret = io_setup(nr_events, &ctx_idp);printf("io_setup ret = %d, ctx_idp = %ld\n", ret, ctx_idp);fd = open("./direct.txt", O_CREAT|O_DIRECT|O_WRONLY, S_IRWXU|S_IRWXG|S_IRWXO);printf("Open fd = %d\n", fd);ret = posix_memalign(&buf, sysconf(_SC_PAGESIZE), sysconf(_SC_PAGESIZE));printf("posix_memalign ret = %d\n", ret);strcpy(buf, "RTOAX >>>>>>>>>>>>>>>>>>>>>> RTOAX");struct iocb *iocbpp = (struct iocb*)malloc(sizeof(struct iocb));memset(iocbpp, 0, sizeof(struct iocb));iocbpp[0].aio_data = buf;iocbpp[0].aio_lio_opcode = IO_CMD_PWRITE;iocbpp[0].aio_reqprio = 0;iocbpp[0].aio_fildes = fd;iocbpp[0].aio_buf = buf;iocbpp[0].aio_nbytes = sysconf(_SC_PAGESIZE);iocbpp[0].aio_offset = 0;ret = io_submit(ctx_idp, 1, iocbpp);printf("io_submit ret = %d, ctx_idp = %ld\n", ret, ctx_idp);ret = io_destroy(ctx_idp);printf("io_destroy ret = %d, ctx_idp = %ld\n", ret, ctx_idp);
}
#define _GNU_SOURCE#include <stdlib.h>
#include <string.h>
#include <libaio.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>#define FILEPATH "./aio.txt"int main()
{io_context_t context;struct iocb io[1], *p[1] = {&io[0]};struct io_event e[1];unsigned nr_events = 10;struct timespec timeout;char *wbuf;int wbuflen = 1024;int ret, num = 0, i;posix_memalign((void **)&wbuf, 512, wbuflen);memset(wbuf, '@', wbuflen);memset(&context, 0, sizeof(io_context_t));timeout.tv_sec = 0;timeout.tv_nsec = 10000000;int fd = open(FILEPATH, O_CREAT|O_RDWR|O_DIRECT, 0644); // 1. 打开要进行异步IO的文件if (fd < 0) {printf("open error: %d\n", errno);return 0;}if (0 != io_setup(nr_events, &context)) {               // 2. 创建一个异步IO上下文printf("io_setup error: %d\n", errno);return 0;}io_prep_pwrite(&io[0], fd, wbuf, wbuflen, 0);           // 3. 创建一个异步IO任务if ((ret = io_submit(context, 1, p)) != 1) {            // 4. 提交异步IO任务printf("io_submit error: %d\n", ret);io_destroy(context);return -1;}while (1) {ret = io_getevents(context, 1, 1, e, &timeout);     // 5. 获取异步IO的结果if (ret < 0) {printf("io_getevents error: %d\n", ret);break;}if (ret > 0) {printf("result, res2: %d, res: %d\n", e[0].res2, e[0].res);break;}}return 0;
}

Linux 原生异步 IO 原理与使用相关推荐

  1. Linux下异步IO(libaio)的使用以及性能

    Linux下异步IO是比较新的内核里面才有的,异步io的好处可以参考这里. 但是文章中aio_*系列的调用是glibc提供的,是glibc用线程+阻塞调用来模拟的,性能很差,千万千万不要用. 我们今天 ...

  2. linux支持异步io吗,Linux 异步IO

    io_submit.io_setup和io_getevents示例 [摘要:注:本宣布正在 io_submit.io_setup战io_getevents战LINUX上的AIO体系挪用.那有一个特别很 ...

  3. # 22.Flink-高级特性-新特性-异步IO\原理

    22.Flink-高级特性-新特性-异步IO-了解 22.1.原理 22.1.1.异步IO操作的需求 https://nightlies.apache.org/flink/flink-docs-rel ...

  4. linux下异步IO的简单例子

    首先,贴一下异步IO中用的的一些结构体,因为平常很少用,整理起来方便查看. aio.h中的struct aiocb struct aiocb{int aio_fildes; /* File desri ...

  5. Linux异步IO实现方案总结

    一.glibc aio 1.名称 由于是glibc提供的aio函数库,所以称为glibc aio. glibc是GNU发布的libc库,即c运行库. 另外网上还有其他叫法posix aio,都是指gl ...

  6. 操作系统与存储:解析Linux内核全新异步IO引擎io_uring设计与实现

    作者:draculaqian,腾讯后台开发工程师 引言 存储场景中,我们对性能的要求非常高.在存储引擎底层的IO技术选型时,可能会有如下讨论关于IO的讨论. http://davmac.org/dav ...

  7. Linux文件系统IO:直接IO原理与实现:缓存I/O、直接I/O

    目录 缓存I/O 缓存I/O的优缺点 直接I/O 直接I/O实现 - direct_IO(), brw_kiovec() 推荐阅读 缓存I/O 一般来说,当调用 open() 系统调用打开文件时,如果 ...

  8. 详解Linux 五种IO模型

    原文:https://www.jianshu.com/p/486b0965c296 上一篇 同步.异步.阻塞.非阻塞 已经通俗的讲解了,要理解同步.异步.阻塞与非阻塞重要的两个概念点了,没有看过的,建 ...

  9. Linux 五种IO模型

    想快速了解,看文末总结. 1 概念说明# 在进行解释之前,首先要说明几个概念: 用户空间和内核空间 进程切换 进程的阻塞 文件描述符 缓存 IO 1.1 用户空间与内核空间## 现在操作系统都是采用虚 ...

最新文章

  1. AI最优论文+代码查找神器:966个ML任务、8500+论文任你选
  2. Database:Database数据库的简介、类型及其区别(关系数据库VS非关系型数据库)、案例应用之详细攻略
  3. The example program of C on point
  4. 电脑音响怎么插_BMW宝马5系G38改原厂全套哈曼卡顿音响+无钥匙进入,厚街宝马原厂改装中心...
  5. mysql_fetch_array 失败_mysql_fetch_array错误
  6. 芯片大神Jim Keller从特斯拉离职,转投“宿敌”英特尔
  7. [转]深入理解C/C++ [Deep C (and C++)]
  8. Android初学第32天
  9. 写偏斜(Write Skew)和丢失更新(Lost Updates)区别
  10. ToolScrip的设置与用法 (C#.NET Winform)
  11. 房屋建筑结构安全自动在线监测系统解决方案
  12. BS架构和CS架构的优缺点
  13. 未受信任的企业级开发者_iPhone提示“未受信任的企业级开发者”怎么办?解决苹果手机APP不信任的方法...
  14. php解析psd文件,PSD解析工具实现(二)
  15. 线性代数学习笔记——第十八讲——抽象矩阵的可逆性
  16. 实现了私聊和群聊功能的聊天工具
  17. 蚂蚁双链通:基于区块链的供应链协作网络
  18. ybt1250 The Castle
  19. iOS10会带来哪些新变化?
  20. C#鸡兔同笼(一个笼子里面关了鸡和兔子(鸡有2 只脚,兔子有4 只脚,没有例外)。已经知道了笼子里面脚的总数a,问笼子里面至少有多少只动物,至多有多少只动物? 请用C#语言实现这个计算过程;)

热门文章

  1. H5实现多图片预览上传,可点击可拖拽控件介绍
  2. Navicat Premium 15 连接Oracle数据库解决方案
  3. oracle到pg不停机增量迁移,研究 Oracle 到 PostgreSQL 的数据迁移 – 以 pgloader 为例 – Phy 的博客...
  4. JavaWeb——关于RequestDispatcher的原理
  5. java数据结构- - - -栈
  6. 记录一次 Ubuntu 16.04 path 错误救机
  7. Eclipse的vim插件viPlugin的安装
  8. 0909 学习操作系统
  9. Tomcat 添加为系统服务 开机自动启动
  10. 一个flash前后台开源框架的的站点