一、同步阻塞 IO(BIO)

当用户线程调用了 read 系统调用,内核(kernel)就开始了 IO 的第一个阶段:准备数据。很多时候,数据在一开始还没有到达(比如,还没有收到一个完整的Socket数据包),这个时候 kernel 就要等待足够的数据到来。

当 kernel 一直等到数据准备好了,它就会将数据从 kernel 内核缓冲区,拷贝到用户缓冲区(用户内存),然后 kernel 返回结果。

从用户线程 read 系统调用开始,用户线程就进入阻塞状态,一直到 kernel 返回结果后,用户线程才解除 block 的状态,重新运行起来。

BIO 的特点:在内核进行 IO 执行的两个阶段,用户线程都被 block 了。

BIO 的优点:程序简单,在阻塞等待数据期间,用户线程挂起,用户线程基本不会占用 CPU 资源。

BIO 的缺点:一般情况下,会为每个连接配套一条独立的线程,或者说一条线程维护一个连接成功的 IO 流的读写。在并发量小的情况下,这个没有什么问题。但是,当在高并发的场景下,需要大量的线程来维护大量的网络连接,内存、线程切换开销会非常巨大。因此,基本上,BIO 模型在高并发场景下是不可用的。

二、同步非阻塞 IO(NIO)

当用户线程调用了 read 系统调用,立即返回,不阻塞线程,用户线程需要不断地发起 IO 系统调用轮询数据是否准备好;

kernel 数据准备好后,用户线程发起系统调用,用户线程阻塞。内核开始复制数据,它就会将数据从 kernel 内核缓冲区,拷贝到用户缓冲区(用户内存),然后 kernel 返回结果。

用户线程解除 block 状态,重新运作起来。

NIO 的特点:应用程序的线程需要不断的进行 I/O 系统调用,轮询数据是否已经准备好,如果没有准备好,继续轮询,直到完成系统调用为止。

NIO 的优点:每次发起的 IO 系统调用,在内核的等待数据过程中可以立即返回,用户线程不会阻塞,实时性较好。

NIO 的缺点:需要不断的重复发起 IO 系统调用,这种不断的轮询,将会不断地询问内核,这将占用大量的 CPU 时间,系统资源利用率较低。

NIO 模型在高并发场景下,也是不可用的。一般 web 服务器不直接使用这种 IO 模型,而是在其他 IO 模型中使用非阻塞 IO 这一特性。java 的实际开发中,也不会涉及这种 IO 模型。

三、IO 多路复用

当用户线程调用了 read 系统调用,用户线程不直接访问 kernel ,而是进行 select/poll/epoll(多路复用器)系统调用。当然,这里有一个前提,需要将目标网络连接,提前注册到 select/poll/epoll 的可查询 socket 列表中(这部分由 kernel 完成)。

用户线程进行 select/poll/epoll 系统调用,线程阻塞,查询可以读的连接,kernel 会查询所有 select/poll/epoll 的可查询 socket 列表,当任何一个 socket 中的数据准备好了,select/poll/epoll 就会返回。

用户线程获得了目标连接后,发起 read 系统调用,线程阻塞,内核开始复制数据,它就会将数据从 kernel 内核缓冲区,拷贝到用户缓冲区(用户内存),然后 kernel 返回结果。

用户线程才解除 block 的状态,用户线程终于真正读取到数据,继续执行。

多路复用 IO 的特点:

  1. 建立在操作系统 kernel 内核能够提供的多路复用系统调用 select/poll/epoll 基础之上的,多路复用 IO 需要用到两个系统调用(system call), 一个 select/poll/epoll 查询调用,一个是 IO 的读取调用。
  2. 和 NIO 模型类似,多路复用 IO 需要轮询,需要有单独的线程不断的进行 select/poll/epoll 轮询,查找出可以进行 IO 操作的连接。
  3. 多路复用 IO 模型与前面的 NIO 模型是有关系的,对于每一个可以查询的 socket,一般都设置成为 non-blocking 模型。

多路复用 IO 的优点:用 select/poll/epoll 的优势在于,它可以同时处理成千上万个连接(connection)。与一条线程维护一个连接相比,I/O 多路复用不必创建线程,也不必维护这些线程,从而大大减小了系统的开销。

多路复用 IO 的缺点:本质上,select/poll/epoll 系统调用,属于同步 IO,也是阻塞 IO,需要在读写事件就绪后,自己负责进行读写,也就是说这个读写过程是阻塞的。

tips:

  1. "多路"指的是多个连接;"复用"指的是复用一个进程/线程进行监控。
  2. Java 的 NIO(New IO)技术,使用的就是 IO 多路复用模型。在 linux 系统上,使用的是 epoll 系统调用。

四、异步非阻塞IO(AIO)

当用户线程调用了 read 系统调用,用户线程立刻就能去做其它的事,用户线程不阻塞。

内核(kernel)就开始了 IO 的第一个阶段:准备数据,当 kernel 一直等到数据准备好了,它就会将数据从 kernel 内核缓冲区,拷贝到用户缓冲区(用户内存)。

然后,kernel 会给用户线程发送一个信号(signal),或者回调用户线程注册的回调接口,告诉用户线程 read 操作完成了。

用户线程读取用户缓冲区的数据,完成后续的业务操作。

AIO 的特点:

  1. 在内核 kernel 的等待数据和复制数据的两个阶段,用户线程都不是 block 的。
  2. 用户线程需要接受 kernel 的 IO 操作完成的事件,或者说注册 IO 操作完成的回调函数到操作系统的内核,因此,异步 IO 有的时候也叫做信号驱动 IO。

AIO 的缺点:需要完成事件的注册与传递,这里边需要底层操作系统提供大量的支持,去做大量的工作。

目前来说, Windows 系统下通过 IOCP 实现了真正的异步 I/O,但是,就目前的业界形式而言,Windows 系统,很少作为百万级以上或者说高并发应用的服务器操作系统来使用。

而在 Linux 系统下,异步 IO 模型在2.6版本才引入,目前并不完善。所以,这也是在 Linux 下,实现高并发网络编程时都是以 IO 复用模型模式为主。(https://github.com/netty/netty/issues/2515

网络 IO 模型简单介绍的更多相关文章

  1. netty学习(一)--linux下的网络io模型简单介绍

    linux的内核将全部的外部设备都看作一个文件来操作,对一个文件的读写操作会调用内核提供的系统命令 ,返回一个file descriptor(fd.文件描写叙述符).而对一个socket的读写也会有对 ...

  2. Unix 网络IO模型介绍

    带着问题阅读 1.什么是同步异步.阻塞非阻塞 2.有几种IO模型,不同模型之间有什么区别 3.不同IO模型的应用场景都是什么 同步和异步.阻塞和非阻塞 同步和异步 广义上讲同步异步描述的是事件中发送方 ...

  3. 网络IO模型:同步IO和异步IO,阻塞IO和非阻塞IO

    同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这个问题其实不同的人给出 ...

  4. 转 网络IO模型:同步IO和异步IO,阻塞IO和非阻塞IO

    此文章为转载,如有侵权,请联系本人.转载出处,http://blog.chinaunix.net/uid-28458801-id-4464639.html 同步(synchronous) IO和异步( ...

  5. 网络IO模型

    同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这个问题其实不同的人给出 ...

  6. [转载] 网络IO模型

    转载自http://blog.csdn.net/zhoudaxia/article/details/8974779 同步(synchronous) IO和异步(asynchronous) IO,阻塞( ...

  7. 5种网络IO模型

    5种网络IO模型(有图,很清楚)   同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到 ...

  8. 5种网络IO模型(有图,很清楚)

    同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这个问题其实不同的人给出 ...

  9. Socket-IO 系列(一)Linux 网络 IO 模型

    Socket-IO 系列(一)Linux 网络 IO 模型 一.基本概念 在正式开始讲 Linux IO 模型前,先介绍 5 个基本概念. 1.1 用户空间与内核空间 现在操作系统都是采用虚拟存储器, ...

随机推荐

  1. vector删除特定元素

    删除vector中小于20的元素,注意要使迭代器失效,不能简单的删除. #include <iostream>#include <vector>using namespace ...

  2. FL Studio里一起安装的ASIO4ALL有什么用?

    在我们安装FL Studio时,正常情况下我们安装FL Studio时最多也就改改安装目录,其他的安装设置一般不会动,但看到FL安装的那些东西我们难道不会感到好奇吗?FL Studio安装包括FL S ...

  3. 对Tarjan——有向图缩点算法的理解

    开始学tarjan的时候,有关无向图的割点.桥.点双边双缩点都比较容易地理解了,唯独对有向图的缩点操作不甚明了.通过对luoguP2656_采蘑菇一题的解决,大致搞清了tarjan算法的正确性. 首先 ...

  4. JDBC【1】-- 入门之增删改查

    目录 1.jdbc是什么 2.使用IDEA开发 2.1 创建数据库,数据表 2.2 使用IDEA创建项目 1.jdbc是什么 JDBC(Java DataBase Connectivity,java数 ...

  5. 深入浅出之mysql索引--上

    当着小萌新之际,最近工作中遇到了mysql优化的相关问题,然后既然提到了优化,很多像我这样的小萌新不容置喙,肯定张口就是 建立索引 之类的. 那么说到底,索引到底是什么,它是怎么工作的?接下来就让我和 ...

  6. kubelet CPU 使用率过高问题排查

    kubelet CPU 使用率过高问题排查 问题背景 客户的k8s集群环境,发现所有的worker节点的kubelet进程的CPU使用率长时间占用过高,通过pidstat可以看到CPU使用率高达100 ...

  7. JAVA在最新版Windows10_1909版本环境下的环境变量配置

    1.配置 1.1新建 JAVA_HOME C:\Program Files\Java\jdk-13.0.2 1.2新建 CLASSPATH .;%JAVA_HOME%\bin;%JAVA_HOME%\ ...

  8. 17.java设计模式之观察者模式

    基本需求: 气象站可以将每天测量到的温度,湿度,气压等等,以公告的形式发布出去(比如发布到自己的网站或第三方) 需要设计开放型API,便于其他第三方也能接入气象站获取数据 提供温度.气压和湿度的接口 ...

  9. maven私服拉取jar失败(内网)

    解决方案: 1.私服没jar,找私服负责人添加 2.私服有拉不下来,重启nexus服务端(负责人做) 3.本地有jar但是idea中没找到,先执行一下reimport,不行的话,随意修改下pom文件, ...

  10. PyQt开发案例:结合QDial实现的QStackedWidget堆叠窗口程序例子及完整代码

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.案例说明 本案例是老猿在学习QStackedWidget中的一个测试案例,该案例使用QStack ...