zoukankan      html  css  js  c++  java
  • Linux IO模型

    同步/异步

    同步IO:同步IO操作导致请求进程阻塞直到IO操作完成。( A synchronous I/O operation causes the requesting process to be blocked until that I/O operation completes)

    异步IO:异步IO操作不会导致请求进程阻塞。(An asynchronous I/O operation does not cause the requesting process to be blocked)

    阻塞/非阻塞

    阻塞:

    非阻塞:

    Linux没有阻塞和非阻塞IO,这是大家意淫出来的,想象一下,发起一个实际IO操作,IO设备未准备好,发起者会被阻塞,或者不被阻塞等待IO设备准备好之后,回调发起者。

    在Linux IO操作中,只有阻塞操作和非阻塞操作,默认所有的文件描述符的操作都是阻塞模式,可以通过下面这个函数设置成非阻塞模式。

    /* set O_NONBLOCK on fd */
    int flags = fcntl(fd, F_GETFL, 0);
    fcntl(fd, F_SETFL, flags | O_NONBLOCK); 

    以下对阻塞和非阻塞不做讨论,为保证语义正确,阻塞和非阻塞的含义仅代表是否调用 fcntl()函数设置 O_NONBLOCK 选项。进程的状态用挂起和运行来表示。

    Linux IO模型

    blocking IO

    如上图所示,

    1:用户进程调用系统调用,用户进程被挂起(wait for data)

    2:内核发起实际的IO操作,等待IO操作完成(wait for data)

    3:实际IO操作完成,copy数据到用户空间(copy data from kernel to user)

    4:copy数据完毕,唤醒用户进程继续运行(copy data from kernel to user)

    用户进程被挂起,必须等待实际的IO操作完成,所以,blocking IO 是阻塞同步IO操作。

    non-blocking IO

    1:用户进程发起IO操作,设置non-blocking参数(wait for data)

    2:内核没有数据,用户进程返回,内核发起实际IO操作,用户进程进入轮询状态(没有就返回)(wait for data)

    3:内核准备好数据,用户进程再次发起recvfrom操作,此时内核需要挂起用户进程,复制数据到用户空间(copy data from kernel to user)

    4:copy数据完毕,唤起用户进程继续运行。

    用户进程在数据没有准备好之前没有被挂起,此时用户进程需要循环调用系统调用,获取数据,在内核把数据准备好之后,挂起用户进程,进行copy数据到用户空间,

    所以,non-blocking IO其实是非阻塞同步IO。

    IO multiplexing

    IO多路复用,或者叫做事件驱动IO模型,模型图如下

    在IO多路复用模型中,

    1:用户进程调用select系统调用,内核没有准备好数据,挂起进程(wait for data)

    2:内核把数据准备好,唤醒进程,返回可读的文件描述符给调用进程(wait for data)

    3:用户进程进行读取系统调用,发起读取数据操作,内核复制数据到用户进程(copy data from kernel to user)

     可以看到,IO多路复用读取一次数据需要俩次系统调用。IO多用复用模型的优势是单进程可以同时处理大量连接。调用select系统调用后,用户进程被挂起,内核负责监视select系统调用提交的文件描述符,有文件描述符准备好,就唤醒用户进程,在IO multiplexing中,对每一个socket,一般都设置成non-blocking模式,但是,如上图所示,整个用户进程一直被挂起。但是进程是被select系统调用挂起,而不是在socket IO挂起。

    Asynchronous I/O

    1:用户进程发起IO 请求,进行内核调用,用户进程返回,内核开始准备数据(wait for data)

    2:数据准备好,复制数据到用户进程(发起请求时提供的AIO控制块)(copy data from kernel to user)

    3:复制完毕,发送信号回调到信号处理程序(用户程序)。

    signal-driven I/O model 

    当描述符准备好时,信号驱动IO模型使用SIGIO信号通知用户 。

    1:用户进程调用sigaction系统调用来注册信号处理程序,信号为SIGIO,不挂起用户进程,立即返回。

    2:当数据准备好之后,发送SIGIO信号到用户进程。

    3:发送recvfrom操作,准备读取数据,内核挂起用户进程,复制数据到用户进程。

    4:复制完毕,唤醒用户进程。

    各种IO模型比较

    所有的blocking,nonblocking,I/O multiplexing signal-driven I/O都是同步IO,因为真实的IO操作recvfrom 会挂起用户进程。

    只有 Asynchronous I/O匹配异步IO的定义。

  • 相关阅读:
    游戏与微博的结合,一个微博后台与前端的设计(基于mysql)。(一)
    UDK 学习点滴 (不断更新)
    多语言版本与UI的展现问题
    用dx11检查你的硬件设备中有几个适配器(adapter)
    多重采样与dx11检查硬件多重采样能力的API
    不均匀点香求时间的问题解
    图片内包含文本制作方法
    vim 搜索 向上 向下 取消高亮
    解决Ucenter 头像上传小收获
    不知道是什么意思
  • 原文地址:https://www.cnblogs.com/shuiyonglewodezzzzz/p/11378262.html
Copyright © 2011-2022 走看看