zoukankan      html  css  js  c++  java
  • I/O模型: 阻塞、非阻塞、I/O复用、同步、异步

    I/O模型不论在实际使用还是准备笔试面试中都是重要的内容,参考Unix网络编程进行总结如下。(尤其注意红色标注处)

    1. 明确I/O考察的对象和流程

    参考Unix网络编程,一个输入操作通常包括两个不同的阶段:

    (1) 等待数据准备好;

    (2) 从内核向进程复制数据。

    对于一个套接字的输入操作,第一步通常涉及等待数据从网络到达,当所等待分组到达时,被复制到内核的某个缓冲区;

    第二步就是把数据从内核缓冲区复制到应用进程缓冲区。

    理解上述两个不同阶段对于后续理解I/O模型尤其是非阻塞I/O与同步I/O关系十分必要

    2. I/O模型

    2.1 阻塞式I/O模型

    阻塞式I/O是最流行的I/O,也是所有套接字默认的I/O。

    (注:所有图片来源 Unix网络编程卷1,第三版)

    如图所示,进程调用recvfrom系统调用,直到数据报到达且被复制到应用进程缓冲区中或发生错误才返回。

    也就是说,进程从调用recvfrom开始到返回的整个时段都是阻塞的(上述两个阶段都是阻塞),recvfrom成功返回后,应用进程才开始处理数据报。

    2.2 非阻塞I/O模型

    根据书中的定义,当所请求的I/O操作非得把本进程投入睡眠才能完成时,不投入睡眠,而是返回一个错误。

    还是考察图示比较清晰。

    如图所示,不同于阻塞式I/O,非阻塞I/O在第一阶段数据没有准备好的时候,不阻塞,而是直接返回一个错误(EWOULDBLOCK)。

    所以一般采用轮询(polling)的方式,应用进程持续轮询内核,查看数据是否准备好。当数据准备好时,被复制到应用进程缓冲区(第二阶段)。

    注*:值得注意的一点是,当第一阶段数据准备完成后,进入第二阶段,内核向内存的复制。这一阶段仍然是阻塞的,这对于后续理解非阻塞与同步的关系十分重要。

    2.3 I/O复用模型

    I/O复用最常见的就是select和epoll,其阻塞发生在上述两个系统调用之一,而不是真正的I/O系统调用上。

    如下图所示:

    当用户进程调用了select,那么整个进程会被阻塞与select。内核会“监视”所有select负责的套接字,当任何一个套接字中的数据准备好了,select就会返回。

    这时候进入第二阶段,完成内核向内存的数据复制。

    I/O复用的优势在于同时等待多个描述符就绪,单就一个描述符可言,其没有优势,反而还会因为多一次select系统调用存在劣势。

    2.4 异步I/O模型

    异步I/O的工作机制是告知内核启动某个操作,并让内核在整个操作(包括第二阶段数据从内核向用户进程的复制)完成后告知我们。

    如下图所示:

    异步I/O要通过调用特殊API实现(如POSIX的aio_read),可以看出,其在两个阶段都是没有对于用户进程的阻塞的,依靠信号通知进程整个过程完成。

    2.5 同步、异步与阻塞、非阻塞、I/O复用的关系

    首先先来再明确一下同步、异步I/O之间的区别。

    书中所述,POSIX把两种术语定义如下:

    同步I/O:导致请求进程阻塞,直到I/O操作完成;

    异步I/O: 不导致请求进程阻塞。

    所以说,阻塞式I/O, 非阻塞I/O, I/O复用由于都导致了请求进程阻塞,所以均属于同步I/O

    (值得注意的是非阻塞I/O,正如之前提示要注意的,其在第二阶段内核向内存复制数据是会导致用户进程的阻塞,所以也属于同步I/O)

    想使用异步I/O,必须使用特殊的API(如linux下AIO,Windows下IOCP等)。

    所以他们的关系如下图所示:

    (注:图片来源陈硕知乎上的解答

    3. 总结

    如下图所示:(暂时忽略信号驱动I/O)

    图中清晰地总结了每种I/O的特点和调用流程。

    可以看出阻塞式、非阻塞式、与I/O复用,其不同之处在于第一阶段,第二阶段的处理方式相同(均阻塞与recvfrom调用),这也是刚才说到的将他们归于同步I/O的原因。

    而异步I/O不存在请求进程阻塞的情况。同时注意前三种I/O模型在第一阶段的处理方式(阻塞,返回+轮询,阻塞于select等),区分这三种I/O模型。

    参考资料:

    1. (美)史蒂文斯(Stevens, W. R. ), (美)芬纳(Fenner,等. UNIX网络编程: 第3版. 1, 套接字联网API[M]. 人民邮电出版社, 2010.

    2. I/O- 同步,异步,阻塞,非阻塞(亡羊补牢篇) http://blog.csdn.net/historyasamirror/article/details/5778378

    3. 知乎问答: 怎样理解阻塞非阻塞与同步异步的区别? https://www.zhihu.com/question/19732473

  • 相关阅读:
    模块(module)
    编译和解释性语言和python运行方式
    管道通信初级
    Page.TryUpdateModel 方法
    运用模型绑定和web窗体显示和检索数据(Retrieving and displaying data with model binding and web forms)
    HttpResponse 类
    ASP.NET中IsPostBack详解
    3.4.1 使用过滤式扩展方法(P43-44)
    使用扩展方法(Chapter3 P39-41)
    C#对象初始或器-Chapter3 P38
  • 原文地址:https://www.cnblogs.com/wangxiaobao/p/5959697.html
Copyright © 2011-2022 走看看