美文网首页
Linux下的网络I/O模型

Linux下的网络I/O模型

作者: YoungJadeStone | 来源:发表于2020-05-17 04:19 被阅读0次

    笔者最近在工作的过程中,涉及到了对Netty的理解,由此展开成对网络I/O模型的归纳,这也是这篇文章的缘由。

    网络I/O模型指的是什么

    首先,我们来明确一下,当我们在说网络I/O模型的时候,指的是linux系统的I/O模式。大的层面来分,I/O模型可以分为:同步IO (sync IO) 和异步IO (async IO)。

    sync v.s. async

    (个人理解:sync和async是处理方式,而不单单是针对IO。)同步处理是指server得到最终结果之后才返回给client;异步处理是指server先返回应答,然后再计算调用结果,计算完最终结果后再通知并返回给client。异步常常指通过另一个thread同时做事情(个人理解:async中client开启一个新thread,主thread去做其他事情)。
    同步和异步的讨论对象是被调用者(server)。

    blocking v.s. non-blocking

    在同步IO里,我们还能更进一步的划分。这里要引入阻塞和非阻塞的概念。
    阻塞是指client一直在等待而且别的事情什么都不做;非阻塞是指client先去忙别的事情。
    阻塞和非阻塞的讨论对象是调用者(client)。

    五种I/O模型

    • 同步IO
      • 【1】阻塞式IO(blocking IO)
      • 【2】非阻塞式IO(non-blocking IO)
      • 【3】IO复用(IO multiplexing)
      • 【4】信号驱动式IO(signal driven IO)
    • 【5】异步IO(asynchronous IO)

    可以把IO call分成两部分:
    server准备数据 + 数据从server拷贝到client的进程中。

    笔者从文章1文章2里看到很生动地描述,我来搬运一下。

    blocking IO

    A拿着一只鱼竿在钓鱼,并且一直在鱼竿前等,等的时候不做其他事情,十分专心。只有鱼上钩的时候,才结束等的动作,把鱼钓上来。(A是client,河是server)

    优点:程序简单,client在阻塞等待数据的时候线程被挂起,几乎不占用CPU资源。
    缺点:每个连接需要独立的线程单独处理,当并发请求量大时为了维护程序,内存、线程切换开销较大,这种模型在实际生产中很少使用。(一群A在钓鱼,每个都专心等,效率很低)
    特点:等待数据被阻塞 + 拷贝数据被阻塞。

    阻塞IO.jpg

    non-blocking IO (NIO)

    B也拿着一只鱼竿在钓鱼,但B在钓鱼的时候,还干别的事情,比如看看书,聊个天。B等的时候每隔固定的时间,就查一下鱼是否已经上钩了(轮询的过程,即polling)。一旦鱼上钩,就停止手中其他工作,把鱼钓上来。

    优点:不会阻塞在内核的等待数据过程,每次发起的 I/O 请求可以立即返回,不用阻塞等待,实时性较好。
    缺点:轮询将会不断地询问内核,这将占用大量的CPU时间,系统资源利用率较低,所以一般Web服务器不使用这种I/O模型。(固定时间检查鱼竿情况的过程)
    特点:等待数据不阻塞 + 拷贝数据被阻塞。

    非阻塞IO.jpg

    IO multiplexing

    C也在钓鱼,但是C拿了很多的鱼竿,一次性有很多鱼竿在等,C不断的查看每个鱼竿是否有鱼上钩。增加了效率,减少了等待的时间。

    优点:可以基于一个阻塞对象,同时在多个描述符上等待就绪,而不是使用多个线程(每个文件描述符一个线程),这样可以大大节省系统资源。
    缺点:当连接数较少时效率相比多线程+阻塞 I/O 模型效率较低,可能延迟更大,因为单个连接处理需要 2 次系统调用,占用时间会有增加。
    特点:等待数据不阻塞 + 拷贝数据被阻塞。

    IO复用.jpg

    signal driven IO

    D也在钓鱼,不同的是,D在鱼竿上挂了个铃铛,鱼上钩的时候,铃铛就会响,D就把鱼钓上来。

    优点:线程并没有在等待数据时被阻塞,可以提高资源的利用率。
    缺点:信号 I/O 在大量 IO 操作时可能会因为信号队列溢出导致没法通知。(铃铛响的太频繁)
    特点:等待数据不阻塞 + 拷贝数据被阻塞。

    信号驱动IO.jpg

    asynchronous I/O (AIO)

    E也想钓鱼,但E(main thread)有事情,于是他雇来了F(new thread),让F帮他等待鱼上钩,一旦有鱼上钩,F就打电话给E,E就会将鱼钓上去。

    这种模型与signal driven IO的主要区别在于:signal driven I/O 是由内核通知应用程序何时启动一个 I/O 操作,而asynchronous I/O 是由内核通知应用程序 I/O 操作何时完成。

    优点:异步 I/O 能够充分利用 DMA 特性,让 I/O 操作与计算重叠。
    缺点:要实现真正的异步 I/O,操作系统需要做大量的工作。在 Linux 系统下,Linux 2.6才引入,目前 AIO 并不完善,因此在 Linux 下实现高并发网络编程时都是以 IO 复用模型模式为主。
    特点:等待数据不阻塞 + 拷贝数据不阻塞

    异步IO.jpg

    五种模型比较

    前四种都是同步IO,它们的第二阶段“拷贝数据”是一样的。区别在于第一阶段。

    IO比较.jpg

    阻塞程度:阻塞IO > 非阻塞IO > IO复用 > 信号驱动IO > 异步IO。

    这五种模型有自己的优缺点。其中AIO比较新。

    相关文章

      网友评论

          本文标题:Linux下的网络I/O模型

          本文链接:https://www.haomeiwen.com/subject/ytadohtx.html