I/O操作是分很多步骤的,如:等待数据、将数据拷贝到内核空间的PageCache(如果是Buffered I/O的话)、将数据拷贝到用户空间等。

同步指的是I/O动作会导致用户进程阻塞,异步则刚好相反。

在Java中,同步异步往往指的是函数是否会等待整个操作处理完成后返回,而阻塞与非阻塞指的往往是用户线程是否需要等待某个事件的到来而阻塞。

五种经典的I/O模型

1. Blocking I/O(阻塞I/O)

请求数据的进程需要一直阻塞等待读取完成才能返回,同时整个读取的动作(这里是recvfrom)也是要同步等待I/O操作的完成才返回。

[使用场景]

这个模型最大的问题在于比较耗时和浪费CPU资源,I/O设备(这里是网卡)往往是一种传输速率较慢的设备,如果在需要很大吞吐量的系统中这种模型就不太适合了。

但是,有时候我们必须等待从I/O设备中传入的数据或者要向它写入某些数据,这个时候阻塞I/O往往是最适合的。比如你的项目中有一个配置文件,里边包含了很多关于项目的配置信息,那么在启动项目的时候就必须等待这个文件的内容被全部读取并解析后才能继续启动项目,这种场景下BIO是最合适的。

2. Nonblocking I/O(非阻塞I/O)

当数据没有准备好的时候,recvfrom调用仍然是同步返回结果。对于整个用户进程而言,它是非阻塞的。

[使用场景]

通常情况下,这是一种低效且十分浪费CPU的操作。

3. I/O Multiplexing(I/O多路复用)--业务层操作

在调用recvfrom之前先调用另外一个系统调用select。整个读取的动作(由两个系统调用组成)是异步的。Java的NIO编程中,多个线程可以向同一个Selector注册多个事件,这样就达到了多路复用的效果。

4. Signal-Driven I/O(信号驱动I/O)--网络层操作

用户进程告诉网卡说,你准备好了叫我一声,然后可以去做别的事情,当网卡来叫的时候就可以继续读操作了。

5. Asynchronous I/O (异步I/O)--操作系统层操作

用户程序使用操作系统提供的异步I/O的系统调用aio_read,这个调用会即时返回,当整个I/O操作完成后它会通知用户进程。典型的异步非阻塞I/O,与「信号驱动I/O」不同的是这个信号是等到所有的I/O动作都执行完之后(数据已经被拷贝到用户空间),才被发送给用户进程。

[使用场景]

在有些平台中,AIO是默认实现的,比如nodejs,其底层其实也是使用阻塞I/O实现的异步,但是对于开发者来说,可以认为它是完全异步的。

Reactor & Proactor模式

把视线从底层的I/O概念中移开,放到普通的应用层实现上,通常基于以上几种I/O模型,可以对应几个编程模式,这里将重点介绍Reactor和Proactor。
[Reactor ---[化工] 反应器; [核] 反应堆; 起反应的人;]

[Proactor ----前摄器]

使用Reactor模式构建的服务端

简单来说,Reactor指的是反应器,在这个模式中有一个角色叫分发器(分发器的叫法多种多样,acceptor、selector或者dispatcher),它会分发各种事件给Reactor,Reactor再去根据不同的事件来做相应的动作。在上图中Reactor进行计算的方式是通过线程池实现的,这是在简单的Reactor模式上又添加了更多的能力,来进一步提高吞吐量,这也是Netty的基本架构。

Reactor的好处和坏处

Reactor带来的好处是显而易见的:

  1. 吞吐量大
  2. 对计算资源(CPU)更充分的利用

当然也有一些坏处:

  1. 系统设计更复杂了
  2. 由于系统更复杂,导致调试很困难
  3. 不适合传输大量数据的场景

Proactor模型

Proactor相比Reactor更好的地方在于,I/O操作和消息通知的过程被下层实现了,业务程序不再需要考虑这些,可以将Proactor看做是对Reactor的又一次封装。根据这个思路可以再进一步,在Reactor模式中不阻塞select,而是在每个业务逻辑执行完后去处理这些事件,也就是在每次循环结束时去处理当前积攒下来的事件(这个模型里如何定义一个循环是很重要的)。

假设在某种场景下,整个程序的目的都是处理单一的事情(比如一个web服务器的目的只是处理请求),我们可以将「与处理请求无关」的逻辑封装到一个框架内,在每次请求处理完后,都执行一次事件的分发和处理,这就是event loop了。很多语言中都有这种概念,如nodejs中的event loop,iOS中的run loop。

内核aio_IO模型_NIO_AIO相关推荐

  1. linux 内核设备管理模型sysfs(进阶篇)

    <linux 内核设备管理模型sysfs(入门篇)>讲述了内核设备管理模型sysfs的基础管理单元kobject和kset,但是在实际过程中很少有驱动工程师有机会直接操作上述结构,linu ...

  2. linux 内核模型,The Linux Kernel Device Model - Overview -- Linux 内核设备模型概述

    --------------------------------------------------------------------------------------------------- ...

  3. WDM内核驱动程序模型分析

    WDM内核驱动程序模型分析  WDM驱动程序是Windows 2000操作系统重要的组成部分,它的正常工作需要有Windows 2000其它内核组件的支持,同时大部分的内核组件也必须同WDM驱动程序交 ...

  4. linux 内核设备管理模型sysfs(入门篇)

    sysfs是linux 内核从2.6中开始引入的设备管理模型,该模型通过一个虚拟的文件系统sysfs 将整个硬件的层级模型显现和组织起来,并将其采用矩阵式管理方式,还是支持热插拔等功能,该设备模型自从 ...

  5. linux内核基本模型,Linux设备模型(1)_基本概念

    Linux设备模型(1)_基本概念 作者:wowo 发布于:2014-2-27 17:01 分类:统一设备模型 1. 前言 在"Linux内核的整体架构"中,蜗蜗有提到,由于Lin ...

  6. linux 内核驱动模型,linux设备驱动模型架构分析 一

    linux设备驱动模型架构分析 一 发布时间:2018-07-04 15:14, 浏览次数:584 , 标签: linux 概述 LDD3中说:"Linux内核需要一个对系统结构的一般性描述 ...

  7. Linux 2.6内核的设备模型

    Linux 2.6 内核的一个重要特色是提供了统一的内核设备模型.随着技术的不断进步,系统的拓扑结构越来越复杂,对智能电源管理.热插拔以及 plug and play的支持要求也越来越高,2.4内核已 ...

  8. linux 物理内存用完了_Linux用户空间与内核空间(理解高端内存)

    Linux内核地址映射模型 x86 CPU采用了段页式地址映射模型.进程代码中的地址为逻辑地址,经过段页式地址映射后,才真正访问物理内存. 段页式机制如下图. Linux内核地址空间划分 通常32位L ...

  9. 北大校友“炼丹”分享:OpenAI如何训练千亿级模型?

    转载自:AI科技评论  |  编译:琰琰 大规模深度神经网络训练仍是一项艰巨的挑战,因为动辄百亿.千亿参数量的语言模型,需要更多的 GPU 内存和时间周期.这篇文章从如何多GPU训练大模型的角度,回顾 ...

  10. Linux内核网络协议栈

    一.注册时机 1.在内核初始化时完成: 2.内核初始化过程(init/main.c):kernel_init()->do_basic_setup()->do_initcalls()-> ...

最新文章

  1. python中意外缩进是什么意思_Python 的缩进是不是反人类的设计?
  2. poj 2411 2663 3420 点头1033
  3. [视频]怎样提升asp.net mvc 软件的性能 - 微软免费视频Improving ASP.NET MVC Application Performance...
  4. 使用Apache配置Tomcat应用整合PHP论坛-Discuz
  5. 《Web前端开发最佳实践》——1.2 Web前端开发现状
  6. 二叉排序树的删除+图解
  7. [html] 隐藏div内文字的方法有哪些?
  8. 串口通讯编程一日通2(Overlapped IO模型)
  9. python装饰器Decorators
  10. Pyqt之QApplication
  11. 构建wifi破解所需的密码库文件
  12. 红黑联盟 php相关资讯
  13. Admob设置Android设备为测试设备(2020年5月7日亲测有效)
  14. 《统计学习方法》 第九章 EM算法(原理+代码)
  15. PCIe接口二,三事
  16. 2021-08-17 WPF控件专题 Canvas 控件详解
  17. PTA 公路村村通(Prim Kruskal)
  18. Oracle完全卸载
  19. xshell中文免费下载及安装(内附百度网盘下载链接,仅供于个人学习使用)
  20. 破解入门(二)-----认识OllyDBG

热门文章

  1. 测试Flume-1.6.0写入HDFS(Hadoop-2.7.2)的简单实例
  2. win7下使用U盘安装Ubuntu Kylin完全详解教程
  3. 教你怎样做项目开发总结报告[转]
  4. 4.Jenkins 2 权威指南 --- 通知与报告
  5. 5.文件操作 --- 系统调用
  6. 34. login-shell 和 环境变量
  7. 6. Zend_Uri
  8. 10. CSS 文本
  9. np合并 python_Python办公自动化自动更新不对称表格
  10. php中的全局变量$GLOBALS与global的区别