Linux 原生异步 IO 原理与使用
目录
什么是异步 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 库,如 libeio
和 glibc 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 原理与使用相关推荐
- Linux下异步IO(libaio)的使用以及性能
Linux下异步IO是比较新的内核里面才有的,异步io的好处可以参考这里. 但是文章中aio_*系列的调用是glibc提供的,是glibc用线程+阻塞调用来模拟的,性能很差,千万千万不要用. 我们今天 ...
- linux支持异步io吗,Linux 异步IO
io_submit.io_setup和io_getevents示例 [摘要:注:本宣布正在 io_submit.io_setup战io_getevents战LINUX上的AIO体系挪用.那有一个特别很 ...
- # 22.Flink-高级特性-新特性-异步IO\原理
22.Flink-高级特性-新特性-异步IO-了解 22.1.原理 22.1.1.异步IO操作的需求 https://nightlies.apache.org/flink/flink-docs-rel ...
- linux下异步IO的简单例子
首先,贴一下异步IO中用的的一些结构体,因为平常很少用,整理起来方便查看. aio.h中的struct aiocb struct aiocb{int aio_fildes; /* File desri ...
- Linux异步IO实现方案总结
一.glibc aio 1.名称 由于是glibc提供的aio函数库,所以称为glibc aio. glibc是GNU发布的libc库,即c运行库. 另外网上还有其他叫法posix aio,都是指gl ...
- 操作系统与存储:解析Linux内核全新异步IO引擎io_uring设计与实现
作者:draculaqian,腾讯后台开发工程师 引言 存储场景中,我们对性能的要求非常高.在存储引擎底层的IO技术选型时,可能会有如下讨论关于IO的讨论. http://davmac.org/dav ...
- Linux文件系统IO:直接IO原理与实现:缓存I/O、直接I/O
目录 缓存I/O 缓存I/O的优缺点 直接I/O 直接I/O实现 - direct_IO(), brw_kiovec() 推荐阅读 缓存I/O 一般来说,当调用 open() 系统调用打开文件时,如果 ...
- 详解Linux 五种IO模型
原文:https://www.jianshu.com/p/486b0965c296 上一篇 同步.异步.阻塞.非阻塞 已经通俗的讲解了,要理解同步.异步.阻塞与非阻塞重要的两个概念点了,没有看过的,建 ...
- Linux 五种IO模型
想快速了解,看文末总结. 1 概念说明# 在进行解释之前,首先要说明几个概念: 用户空间和内核空间 进程切换 进程的阻塞 文件描述符 缓存 IO 1.1 用户空间与内核空间## 现在操作系统都是采用虚 ...
最新文章
- AI最优论文+代码查找神器:966个ML任务、8500+论文任你选
- Database:Database数据库的简介、类型及其区别(关系数据库VS非关系型数据库)、案例应用之详细攻略
- The example program of C on point
- 电脑音响怎么插_BMW宝马5系G38改原厂全套哈曼卡顿音响+无钥匙进入,厚街宝马原厂改装中心...
- mysql_fetch_array 失败_mysql_fetch_array错误
- 芯片大神Jim Keller从特斯拉离职,转投“宿敌”英特尔
- [转]深入理解C/C++ [Deep C (and C++)]
- Android初学第32天
- 写偏斜(Write Skew)和丢失更新(Lost Updates)区别
- ToolScrip的设置与用法 (C#.NET Winform)
- 房屋建筑结构安全自动在线监测系统解决方案
- BS架构和CS架构的优缺点
- 未受信任的企业级开发者_iPhone提示“未受信任的企业级开发者”怎么办?解决苹果手机APP不信任的方法...
- php解析psd文件,PSD解析工具实现(二)
- 线性代数学习笔记——第十八讲——抽象矩阵的可逆性
- 实现了私聊和群聊功能的聊天工具
- 蚂蚁双链通:基于区块链的供应链协作网络
- ybt1250 The Castle
- iOS10会带来哪些新变化?
- C#鸡兔同笼(一个笼子里面关了鸡和兔子(鸡有2 只脚,兔子有4 只脚,没有例外)。已经知道了笼子里面脚的总数a,问笼子里面至少有多少只动物,至多有多少只动物? 请用C#语言实现这个计算过程;)
热门文章
- H5实现多图片预览上传,可点击可拖拽控件介绍
- Navicat Premium 15 连接Oracle数据库解决方案
- oracle到pg不停机增量迁移,研究 Oracle 到 PostgreSQL 的数据迁移 – 以 pgloader 为例 – Phy 的博客...
- JavaWeb——关于RequestDispatcher的原理
- java数据结构- - - -栈
- 记录一次 Ubuntu 16.04 path 错误救机
- Eclipse的vim插件viPlugin的安装
- 0909 学习操作系统
- Tomcat 添加为系统服务 开机自动启动
- 一个flash前后台开源框架的的站点