zoukankan      html  css  js  c++  java
  • Linux IO模式和select,poll,epoll解释

    一些概念:

    虚拟空间:是进程所看到的所有地址组成的空间。虚拟空间某个进程对所有分配给它的所有物理地址的重新映射。

    寻址返回与计算机的位数有关系。分为内核空间与用户空间。针对32位的Linux系统,最高的1G字节为内核空间。最低的3G字节为用户空间。

    进程阻塞:这是进程自身的一种主动行为。当进程进入阻塞状态的时候,占用CPU资源。

    文件描述符fd:非负整数,是一个索引值。指向内核为每一个进程所维护的该进程的打开文件记录表。

    缓存IO:大多数文件系统的默认IO都是缓存IO。过程是:数据先被拷贝到操作系统的内核缓冲区(页缓存 page cache)中,然后再拷贝到应用程序的地址空间。

    举例:

    当一个read操作发生时,会经历两个阶段:

    1 等待数据准备(waiting for the data to be ready)

    2 将数据从内核拷贝到进程中(copying the data from the kernel to the process)

    LInux IO模式分为5种:

    阻塞IO(blocking IO)

    非阻塞IO(non-blocking IO)

    IO多路复用(IO multiplexing)

    信号驱动IO(signal driven IO) (不常用)

    异步IO(asynchronous IO)

    阻塞IO(blocking IO):

    在Linux中,默认情况下,所有的socket都是blocking的。图示如下:

     

    上面提到了两个阶段,再blocking IO里,两个阶段都被阻塞了

    非阻塞IO(nonblocking IO)

    图示如下:

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

    IO多路复用(IO multiplexing)

    也称为event driven IO,包括select,poll,epoll。单个进程可以同时处理多个网络连接的IO。

    原理是select,poll,epoll会不断轮询所负责的socket,当socket有数据到达了,会通知用户进程

    图示如下:

    用户进程调用了select,整个进程会被block。同时kernel会监视所有select负责的socket,当任何一个socket中的数据准备好了,select就会返回。这个时候再调用read,将数据从kernel拷贝到用户进程

    在这里,我们使用了select,recvfrom两个system call,相比较blocking IO的一个system call(recvfrom)效率更差,使用select的优势在于它可以同时处理多个connection,而不是对于单个连接处理的更快。

    所以,当要处理的连接数不是很高的话,使用select/epoll的web server不一定比使用multi-threading + blocking IO的web server性能更好,可能延迟更大。

    在IO multiplexing model里,对于每一个socket,一般都设置成non-blocking的。大多数情况下,整个用户的process被select函数所阻塞

    异步IO(asynchronous IO)

    异步IO的流程如下:

    用户进程发起read之后立即返回,去做其他的事情。

    kernel收到read之后,不会对用户进程产生任何block。而是等待数据准备完成,将数据拷贝到用户内存,然后给用户进程发送一个signal,告诉read操作完成了

    总结:

    blocking和non-blocking的区别

    调用blocking IO会一直block住对应的进程直到操作完成,而non-blocking IO在kernel还准备数据的情况下立即返回

    syschronous IO和asynchronous IO的区别

    判断同步IO,异步IO的关键点在于在真实的IO操作里(比如recvfrom),进程有没有被阻塞。

    在non-blocking中,如果kernel的数据没有准备好,这时候固然不会block进程。但是当kernel中数据准备好的时候,recvfrom会将数据从kernel拷贝到用户内存里,这时候进程是被block的,所以non-blocking,blocking均是同步IO

    而异步IO是当进程发起IO操作之后,立即返回,再也不理睬,知道收到kernel发送的IO完成的信号。在这个过程中,进程完全没有被block

    同步异步的区分点在于:用户进程是怎样知道数据ok了的(自己主动check得知,还是接收到的signal得知);数据在kernel中准备完成之后,是谁负责拷贝数据到用户内存的(自己拷贝还是kernel负责拷贝的)

    各个IO model的比较图:

    本文从以下ref中整理而来:

    ref: https://segmentfault.com/a/1190000003063859

  • 相关阅读:
    Asp.net使用DevExpress的某些控件不能操作ViewState的解决方案
    关于 vue 循环组件,组件内有根据要求请求select下拉列表,组件内还有自身组件,select下拉列表无法正确获取的问题解决
    Vue+axios请求本地json
    关于vuevideoplayer 实现跳转到特定位置并自动播放
    VueQuillEditor回显不显示空格的处理办法
    elementui 的CascaderPanel级联面板类型 懒加载 回显
    elementui 中的文本域的autosize的意思
    解决 [Element Warn][Form]model is required for validate to work!
    初涉simulink
    arm学习计划
  • 原文地址:https://www.cnblogs.com/geeklove01/p/8979760.html
Copyright © 2011-2022 走看看