目录

一、概念

二、流程

三、举例说明


一、概念

异步I/O模型:是进程通过系统调用告知内核启动某个I/O操作,内核启动I/O操作后立刻返回到进程,进程在I/O操作发生期间继续执行程序,当IO操作完成或遭遇错误时,内核以进程在I/O系统调用中指定的某种方式通知进程操作结果。

二、流程

说明:首先用户态进程告诉内核态需要什么数据,然后用户态进程继续执行程序,内核等待用户态需要的数据准备好,然后将数据复制到用户空间,操作完成后才告诉用户态进程结果,然后用户态进程直接处理用户空间的数据。

注意:将数据由内核缓存复制到用户态缓存的过程是内核进行,用户态进程是不阻塞的(用户进程不参与)。在复制数据到用户空间这个时间段内,用户态进程在正常执行程序。

三、举例说明

Linux原生aio

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

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

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 的结果。

实现代码:

#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 原生 AIO 的使用过程,主要有以下步骤:

  • 通过调用 open 系统调用打开要进行异步 IO 的文件,要注意的是 AIO 操作必须设置 O_DIRECT 直接 IO 标志位。
  • 调用 io_setup 系统调用创建一个异步 IO 上下文。
  • 调用 io_prep_pwrite 或者 io_prep_pread 函数创建一个异步写或者异步读任务。
  • 调用 io_submit 系统调用把异步 IO 任务提交到内核。
  • 调用 io_getevents 系统调用获取异步 IO 的结果。

在上面的例子中,我们获取异步 IO 操作的结果是在一个无限循环中进行的,其实 Linux 还支持一种基于 eventfd 事件通知的机制,可以通过 eventfdepoll 结合来实现事件驱动的方式来获取异步 IO 操作的结果,有兴趣可以查阅相关的内容。

IO模型-异步I/O模型相关推荐

  1. IO模型及Netty线程模型

    Netty简介 1. 简介 版本:Netty4.X Netty是基于NIO的异步网络通信框架 能快速的搭建高性能易扩展的网络应用程序(服务器/客户端) 2. 特征 设计 适用于各种传输类型的统一API ...

  2. 【多线程】0.理解一下5种IO模型、阻塞IO和非阻塞IO、同步IO和异步IO

    5种IO模型.阻塞IO和非阻塞IO.同步IO和异步IO 看了一些文章,发现有很多不同的理解,可能是因为大家入切的角度.环境不一样.所以,我们先说明基本的IO操作及环境. 本文是在<UNIX网络编 ...

  3. 重叠IO模型-异步IO

    重叠IO模型-异步IO http://laiba.tianya.cn/laiba/CommMsgs?cmm=959&tid=2701316824681802728 说到重叠模型首先还是提一下异 ...

  4. Linux网络编程 | IO模型 :阻塞IO、非阻塞IO、信号驱动IO、异步IO、多路复用IO

    目录 IO模型 阻塞与非阻塞 同步与异步 阻塞IO 非阻塞IO 信号驱动IO 多路复用IO 异步IO IO模型 根据各自的特性不同,IO模型被分为阻塞IO.非阻塞IO.信号驱动IO.异步IO.多路复用 ...

  5. 5种网络IO模型:阻塞IO、非阻塞IO、异步IO、多路复用IO、信号驱动IO

    目录 前言 阻塞IO(blocking IO) 非阻塞IO(non-blocking IO) 多路复用IO(IO multiplexing) 异步IO(Asynchronous I/O) 模型间的区别 ...

  6. IO模型 :阻塞IO、非阻塞IO、信号驱动IO、异步IO、多路复用IO

    文章目录 IO模型 阻塞IO 非阻塞IO 信号驱动IO 多路复用IO 异步IO IO模型 根据各自的特性不同,IO模型被分为阻塞IO.非阻塞IO.信号驱动IO.异步IO.多路复用IO五类. 最主要的两 ...

  7. Reactor模型和Proactor模型:同步IO与异步IO

    Table of Contents 服务端的线程模型 2种fd 3种事件 Reactor模型-同步I/O 1.单Reactor单线程模型 2.单Reactor多线程模型 3.主从Reactor多线程模 ...

  8. 程序员成长之旅——同步IO和异步IO(五种IO模型)

    程序员成长之旅--同步IO和异步IO(五种IO模型) 同步和异步 同步 异步 消息通知 场景比喻 阻塞和非阻塞 阻塞 非阻塞 事例 同步IO 阻塞IO 非阻塞IO 信号驱动IO 多路转接IO 异步IO ...

  9. 基础服务器 IO 模型 Proactor 模型 Reactor 模型 IO 多路复用 异步 IO 模型 Linux 服务器开发 网络编程服务器模型

    本文主要记录服务器的 IO 模型的类型(从多路复用,异步 IO 讲到 Proactor Reactor 模型),包括 Real World nginx 和 apache ,kafka 等分析,配备自洽 ...

最新文章

  1. python字符串、元组常用操作
  2. Erlang vs Java memory architecture (zz)
  3. iOS开发(7)通过uiimageView浅谈UIView
  4. easyui中的datetimebox 只显示年月日_设置Win10任务栏显示星期几方法
  5. Visual Studio 2010 单元测试之一---普通单元测试:http://blog.csdn.net/tjvictor/archive/2011/02/09/6175362.aspx...
  6. ubuntu codeblocks10.05安装全过程 (包含注意事项:安装后不能启动)
  7. 跨浏览器用javascript获取窗口的位置和大小
  8. 《无边界触达——数字化时代的高等教育》白皮书,附下载地址
  9. 多模态关键任务与应用综述(从表示到融合,从协同学习到关键技术梳理)
  10. 三坐标测量机(CMM)测头初步了解
  11. 信号峰峰值Vpp与功率和dbm的换算
  12. slf4j、log4j日志级别与配置
  13. java中new对象_java new对象的理解
  14. h5拍摄身份证_H5接口调用,身份证识别
  15. C语言pow函数的精度问题
  16. 超大图片的储存/处理/显示
  17. 史上首例!阿里程序员写的代码,被国家博物馆收藏了!
  18. C++图片格式转换:BMP转JPEG
  19. 普通浏览器打开微信页面出现验证的解决方法
  20. 会声会影批量处理素材设置教程

热门文章

  1. PCA实验人脸库-人脸识别(四)
  2. Java基础-GUI编程讲解
  3. 关系型数据库与NoSql数据库的优缺点
  4. ai作文批改_网易有道词典上线AI作文批改功能 可自动批改雅思、四六级英语作文...
  5. EAS运行期license过期的解决办法。
  6. 编写网页项目的基本步骤——Html
  7. android gps定位完整代码,android GPS定位 (完整代码实例)
  8. 华兴资本确定IPO发行价 募集资金将达3.96亿美元
  9. SteamOS 2.0,Raspberry Pi上的仿真器以及更多开放游戏新闻
  10. 数据挖掘导论 复习一(介绍+数据预处理方法+定性归纳)