• 阻塞IO, 非阻塞IO, 同步IO,异步IO


    阻塞IO, 非阻塞IO, 同步IO,异步IO 介绍


    先说明几个概念

    • 用户空间与内核空间
      • 为了保证用户进程不能直接操作内核(kernel),保证内核的安全,操心系统将虚拟空间(内存)划分为两部分,一部分为内核空间,一部分为用户空间。
      • 针对linux操作系统而言,将最高的1G字节(从虚拟地址0xC0000000到0xFFFFFFFF),供内核使用,称为内核空间,而将较低的3G字节(从虚拟地址0x00000000到0xBFFFFFFF),供各个进程使用,称为用户空间。
    • 进程切换
      • 为了控制进程的执行,内核必须有能力挂起正在CPU上运行的进程,并恢复以前挂起的某个进程的执行。这种行为被称为进程切换。
    • 进程的阻塞
      • 正在执行的进程,由于期待的某些事件未发生,如请求系统资源失败、等待某种操作的完成、新数据尚未到达或无新工作做等,则由系统自动执行阻塞原语(Block),使自己由运行状态变为阻塞状态。可见,进程的阻塞是进程自身的一种主动行为,也因此只有处于运行态的进程(获得CPU),才可能将其转为阻塞状态。当进程进入阻塞状态,是不占用CPU资源的。
    • 文件描述符fd
      • 文件描述符(File descriptor)是计算机科学中的一个术语,是一个用于表述指向文件的引用的抽象化概念。
      • 文件描述符在形式上是一个非负整数。实际上,它是一个索引值,指向内核为每一个进程所维护的该进程打开文件的记录表。当程序打开一个现有文件或者创建一个新文件时,内核向进程返回一个文件描述符。在程序设计中,一些涉及底层的程序编写往往会围绕着文件描述符展开。但是文件描述符这一概念往往只适用于UNIX、Linux这样的操作系统。
    • 缓存 I/O
      • 缓存 I/O 又被称作标准 I/O,大多数文件系统的默认 I/O 操作都是缓存 I/O。在 Linux 的缓存 I/O 机制中,操作系统会将 I/O 的数据缓存在文件系统的页缓存( page cache )中,也就是说,数据会先被拷贝到操作系统内核的缓冲区中,然后才会从操作系统内核的缓冲区拷贝到应用程序的地址空间。
      • 缓存 I/O 的缺点:数据在传输过程中需要在应用程序地址空间和内核进行多次数据拷贝操作,这些数据拷贝操作所带来的 CPU 以及内存开销是非常大的。

    阻塞 I/O(blocking IO)

    • 在linux中,默认情况下所有的socket都是blocking,一个典型的读操作流程大概是这样:
    • 个人理解:
      当程序(APP)发起一个read IO:
      1 . 调用系统call,这时内核(kernel)开始准备数据(例:socket等待客户端进入),这个过程会发生阻塞(block);
      2 . 应用程序和操作系统都在等待内核准备数据;
      3 . 当数据准备好后,从内核拷贝数据给用户(拷贝这个过程也是阻塞的)
      4 . 给进程返回一个拷贝完成,整个read IO完成;
    • blocking IO的特点就是在IO执行的两个阶段(准备数据、拷贝数据)都被block了。

    非阻塞I/O(non-blocking IO)

    • linux下,可以通过设置socket使其变为non-blocking。当对一个non-blocking socket执行读操作时,流程是这个样子:

    • 个人理解:
      当(APP)发起一个read IO:
      1 . read调用系统的call,当内核数据没有准备好,立刻返回一个error;
      2 . 用户得到这个error可以知道数据还没准备好,于是,用户可以再次发送请求;
      3 . 当内核数据准备好了,并且再次收到用户请求,马上开始从内核拷贝数据给用户;
      4 . 拷贝完成,用户收到数据和一个return,read IO完成。

    • nonblocking IO的特点是用户进程需要不断的主动询问kernel数据好了没有。

    多路复用I/O (multiplexing IO)

    • IO multiplexing就是我们说的select,poll,epoll,有些地方也称这种IO方式为event driven IO。select/epoll的好处就在于单个process就可以同时处理多个网络连接的IO。它的基本原理就是select,poll,epoll这个function会不断的轮询所负责的所有socket,当某个socket有数据到达了,就通知用户进程。

    • 个人理解
      当用户发起一个或多个read IO
      1 . 用户把一个或多个read IO交给select;
      2 . select负责轮询内核是否准备好数据;
      3 . 有任何一个准备好数据,select立刻返回;
      4 . 用户收到这个返回,调用系统call,内核收到请求,开始从内核拷贝数据给用户;
      5 . 拷贝完成,用户收到return,readIO完成。

    • I/O 多路复用的特点是通过一种机制一个进程能同时等待多个文件描述符,而这些文件描述符(套接字描述符)其中的任意一个进入读就绪状态,select()函数就可以返回。

    异步 I/O(asynchronous IO)

    • inux下的asynchronous IO其实用得很少。先看一下它的流程:
      • 个人理解
        当用户发起一个read:
        1 . 发起请求,调用系统call,立刻收到返回;
        2 . 用户去干其他事情,read交给内核;
        3 . 内核完成数据准备,拷贝数据后,给用户一个signal;
        4 . 用户收到signal和数据,read操作完成
    • 相当于,用户到银行办理业务,递交资料后就不用管了;银行完成所有操作,直接将账单(数据)邮寄给用户,并给用户打电话(完成信号);期间用户可以做自己的事情。

    non-blocking IO和asynchronous IO的区别:

    • 在non-blocking IO中,虽然进程大部分时间都不会被block,但是它仍然要求进程去主动的check,并且当数据准备完成以后,也需要进程主动的再次调用recvfrom来将数据拷贝到用户内存。而asynchronous IO则完全不同。它就像是用户进程将整个IO操作交给了他人(kernel)完成,然后他人做完后发信号通知。在此期间,用户进程不需要去检查IO操作的状态,也不需要主动的去拷贝数据。

    文档

    <wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">

  • 相关阅读:
    Nhibernate 在一个项目中连接不同的数据库。记录
    sql2005 向2000导入数据。一些注意事项
    iis发布系统问题总结 .....关于handler的重写的应用
    ExecutorService 线程池
    Spring Boot 访问静态资源
    spring boot的核心注解
    日期处理工具类
    Json解析工具类
    (技能篇)Mysql在linux下的全量热备份
    Linux相关命令
  • 原文地址:https://www.cnblogs.com/limich/p/7477119.html
Copyright © 2020-2023  润新知