zoukankan      html  css  js  c++  java
  • UNIX五种I/O模型

    UNIX的五种I/O模型:阻塞式I/O模型,非阻塞式I/O模型,I/O复用模型,信号驱动式I/O模型,异步I/O模型。这些概念看似容易混淆,从UNIX底层的I/O操作的角度来分析,其实不难理解。

    一个输入操作通常包括以下两个阶段:

    1. 等待数据准备好;包括等待数据从网络中到达,数据到达后存入内核的缓冲区中。
    2. 从内核向进程复制数据。把数据从内核缓冲区复制到进程缓冲区。

    下面要讲的五种I/O模型实际上就是在这两个阶段中的阻塞策略不同。接下来以UDP的recvfrom为例,进行说明。

    阻塞式I/O模型

    blocking IO,最直观的I/O模型。应用进程调用recvfrom方法时,会进行阻塞,直到两个阶段都结束,数据复制到进程缓冲区时,方法才返回。成功返回后,应用程序再进行后续工作。流程如下图所示:

    image

    非阻塞式I/O模型

    此种模型下,recvfrom方法可立即返回。若内核数据没有准备好,则返回一个错误;若数据准备好,进行第二阶段复制操作,再返回成功指示。流程如下图所示:

    image

    该种模型较为少见,因为往往需要应用程序持续轮询内核,看看操作有没有准备就绪。这样会耗费大量CPU时间。

    I/O复用模型

    I/O复用是生产中最常见的网络模型。调用select或者poll方法去查看内核中数据是否准备好,准备完毕即返回,否则保持阻塞。但是请注意,select调用和recvfrom调用往往不在一个线程中,所以此处的阻塞不会影响真正的IO操作。当套接字可读,select返回,回调执行recvfrom,完成输入操作。如下图所示:

    image

    如果只是线性地看两个阶段是否有阻塞,IO复用似乎没什么优势。但实际上,使用select的优势在于“多路复用”,即一个selector等待多个文件描述符。

    信号驱动式I/O模型

    信号驱动式I/O模型,先通过sigaction调用安装一个信号处理函数,并立即返回。当套接字可读时,内核发送SIGIO信号通知应用程序,执行recvfrom方法执行IO输入。如下图所示:

    image

    这种模型,在接收到SIGIO信号之前,进程不会被阻塞。

    异步I/O模型

    前面四种IO模型,实际上在第二阶段(从内核缓冲区读取数据到用户缓冲区)都是阻塞的。而异步I/O模型在两个阶段都是非阻塞的。即先告知内核启动IO操作,立即返回,在两个阶段(准备数据和读取数据)全部完成时,内核发送信号通知用户进程。如下图所示:
    image

    各种I/O模型的比较

    首先明确两个概念:同步I/O异步I/O,POSIX对其定义如下:

    • 同步I/O(synchronous I/O operation):导致请求进程阻塞,直到IO操作完成;
    • 异步I/O(asynchronous I/O operation):不导致请求进程阻塞。

    五种模型的对比如下

    image
    五种I/O模型中,除了异步I/O,其余四种或多或少都有阻塞的过程。因此,按照POSIX的标准,阻塞式I/O模型、非阻塞式I/O模型、I/O复用模型、信号驱动式I/O模型,都称之为同步I/O。

  • 相关阅读:
    pyCharm报错"your evaluation license has expired, pycharm will now exit"解决方法(实测)
    (转)python selenium-webdriver 元素操作之鼠标和键盘事件
    转载:PICT使用教程(设计测试用例工具)
    转载:小米电视怎么安装爱奇艺
    关于VMware 15搭建MacOS 10.14后无法播放在线视频和客户端视频的问题
    Reference resources
    centos7 启用iptables
    disabling IPv6 name/address support: Address family not supported by protocol
    rngd.service 启动失败的处理
    mdadm Raid5 /dev/md0 lost a disk and recovery from another machine
  • 原文地址:https://www.cnblogs.com/buptleida/p/12944045.html
Copyright © 2011-2022 走看看