美文网首页
聊聊面试中的IO

聊聊面试中的IO

作者: lucasgao | 来源:发表于2021-03-11 20:32 被阅读0次

    [toc]

    I/O模型

    阻塞I/O

    最常见的I/O模型,默认情况下通过read或者write等系统调用读写文件或者网络时,都会被阻塞

    blocking-io-mode

    操作系统中多数的I/O操作如上,一旦执行,会陷入阻塞等待I/O操作ready。

    非阻塞I/O

    可以通过 O_NONBLOCK字段标志为非阻塞的。

    int flags = fcntl(fs,F_GETFL,0);
    fcntl(fd, F_SETFL, flags | O_NONBLOCK);
    

    通过fcntlO_NONBLOCK我们可以把一个文件描述符修改为非阻塞的。此后当我们进行read操作的时候,如果数据没有ready,则会返回EAGAIN的错误。如果已经ready,则它的返回值大于0。

    non-blocking-io-mode

    异步I/O

    同步方式在处理I/O事件的时候,必须阻塞在某个方法上面等待I/O事件完成。(无论阻塞I/O,还是上面说的非阻塞式I/O都是同步的)。上面的非阻塞只是我们不需要阻塞等待数据ready,但是真正的io操作还是阻塞的。

    异步的方式,就是将所有的I/O读写交给操作系统去处理。

    image-20210206160159479

    异步IO跟信号驱动IO很相似,但是不同点如上所说,触发的时机不一致。异步io只是在所有操作都ready的时候才会通知。

    对于一次I/O访问,可以分为2部分:

    1. 等待数据准备就绪
    2. 将数据从内核copy到进程。

    I/O复用

    目前最多的实现,单独放到一章去讲,这里给出大概交互

    image-20210206160600266

    信号驱动I/O

    监听io信号,等数据ready之后开始处理

    image-20210206161145085

    无论如何处理SIGIO信号,这种模型的优势在于等待数据报到达期间进程不 被阻塞。主循环可以继续执行,只要等待来自信号处理函数的通知:既可以是数 据已准备好被处理,也可以是数据报已准备好被读取。

    五种I/O模型对比

    image-20210206161256697

    前4种模型的主要区别在于第 一阶段,因为它们的第二阶段是一样的:在数据从内核复制到调用者的缓冲区期 间,进程阻塞于recvfrom调用。相反,异步I/O模型在这两个阶段都要处理,从 而不同于其他4种模型。

    前4种模型——阻塞式I/O模型、非阻塞式I/O模型、I/O 复用模型和信号驱动式I/O模型都是同步I/O模型,因为其中真正的I/O操作 (recvfrom)将阻塞进程。只有异步I/O模型与POSIX定义的异步I/O相匹配。

    I/O多路复用

    鉴于目前这是最常用的方式,所以单独说说

    开始之前的个人疑问

    1. IO多路复用跟信号驱动有什么不同。

      信号驱动的使用比较少,应该是不灵活

    一种在单个线程上同时处理多个事件流的方法

    select

    image-20210206173828848

    缺点:

    • 文件描述符数量限制
    • 线性扫描,性能很差
    • fd维护

    poll

    缺点:

    • 大量的fd数组被整体复制于内核态和用户态之间,而不管这样的复制是不是有意义。
    • 同select相同的是调用结束后需要轮询来获取就绪描述符。

    epoll

    轮询改为定点

    go的网络多路复用

    相关文章

      网友评论

          本文标题:聊聊面试中的IO

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