zoukankan      html  css  js  c++  java
  • IO-同步,异步,阻塞,非阻塞

    Stevens在文章中一共比较了五种IO Model:
    blocking IO
    nonblocking IO
    IO multiplexing
    signal driven IO
    asynchronous IO
    由于signal driven IO在实际中并不常用,所以我这只提及剩下的四种IO Model。
    对于一个network IO (这里我们以read举例),它会涉及到两个系统对象,
    一个是调用这个IO的process (or thread),另一个就是系统内核(kernel)。
    当一个read操作发生时,它会经历两个阶段:
    1 等待数据准备 (Waiting for the data to be ready)
    2 将数据从内核拷贝到进程中 (Copying the data from the kernel to the process)

    阻塞式I/O模型:第一步一次system call
    第一步通常涉及等待数据从网络中到达。当所有等待分组到达时,它被复制到内核中的某个缓冲区。
    第二步就是把数据从内核缓冲区复制到应用程序缓冲区。

    非阻塞式I/O:第一步多次system call,第二步一次
    当用户进程发出read操作时,如果kernel中的数据还没有准备好,
    那么它并不会block用户进程,而是立刻返回一个error。
    从用户进程角度讲 ,它发起一个read操作后,并不需要等待,而是马上就得到了一个结果。
    用户进程判断结果是一个error时,它就知道数据还没有准备好,于是它可以再次发送read操作。
    一旦kernel中的数据准备好了,并且又再次收到了用户进程的system call,
    那么它马上就将数据拷贝到了用户内存,然后返回。
    所以,用户进程其实是需要不断的主动询问kernel数据好了没有。

    I/O多路复用:第一,二步开始各一次system call
    虽然I/O多路复用的函数也是阻塞的,但是其与以上两种还是有不同的,
    I/O多路复用是阻塞在select,epoll这样的系统调用之上,而没有阻塞在真正的I/O系统调用如recvfrom之上.

    信号驱动式I/O:和多路复用差不多,只是用信号代替通知,不常用。

    异步I/O:第一步一次system call
    工作机制是告知内核启动某个操作,并让内核在整个操作(包括将数据从内核拷贝到用户空间)完成后通知我们

    生活实例:老张要烧水,再泡茶喝
    1.老张放水壶到火上,等水开了,再泡茶喝。
    2.老张放水壶到火上,反复去看会儿电视,反复回来check水开了没,反复几次水开了开始泡茶喝。
    3.老张在走廊烧水,其他居民也在楼道烧水,有个在走廊乘凉的邻居,让ta帮忙看谁家的水开了就帮忙喊下,然后开始泡茶。
    4.老张买了个自动冲茶机,打开后老张就去看电视了。听到滴滴滴的提示声知道茶已经泡好了。
    前3个其实都是同步的。3的阻塞就是哪个看护者调用。

    http://blog.csdn.net/historyasamirror/article/details/5778378
    https://www.zhihu.com/question/19732473

  • 相关阅读:
    BestCoder Round #65
    Codeforces Round #334 (Div. 2)
    二叉搜索树(排序二叉树)
    二叉搜索树 POJ 2418 Hardwood Species
    差分约束系统 POJ 3169 Layout
    思维题(转换) HDU 4370 0 or 1
    SPFA+Dinic HDOJ 3416 Marriage Match IV
    图论 SRM 674 Div1 VampireTree 250
    SPFA(建图) HDOJ 4725 The Shortest Path in Nya Graph
    SPFA(负环) LightOJ 1074 Extended Traffic
  • 原文地址:https://www.cnblogs.com/xiao0913/p/5367481.html
Copyright © 2011-2022 走看看