zoukankan      html  css  js  c++  java
  • 阻塞与非阻塞IO step by step

    谈到IO,阻塞、非阻塞,异步、同步是绕不开的话题。说实话,我也没搞清楚,网上查了许多资料,大家众说纷纭,一种比较靠谱的说法是:”在处理 IO 的时候,阻塞和非阻塞都是同步 IO,使用使用了特殊的API才是异步IO“。知乎的回答相对来说可信度高点,大家姑且可以先看着:

    http://www.zhihu.com/question/19732473

    这些资料大多说理,我还是想通过一些例子,以我们看到到摸得着的方式,慢慢搞懂阻塞、非阻塞以及异步同步间的关系。所以这一系列将是我的读书笔记,因为我也摸着石头过河,等过完河我再整理IO这一个系列的文章。

    阻塞和非阻塞

    阻塞与非阻塞是个概念,概念背后肯定有很多内容嘛,我们一一展开。首先,主语是操作系统(OS),宾语是进程,也就是说,阻不阻塞都是针对进程的;我们知道阻塞与不阻塞是针对于同一问题的两种处理方式,那么这个问题又是什么呢?答,是当我进程要读数据时,数据还没准备好,在这种情况下操作系统的策略。用户态进程想走下去,需要读取硬件上收集的数据,用户态到硬件间的距离,隔着一个操作系统,操作系统此时向用户态提供了两种解决方案:①阻塞,进程在等待队列上睡觉,到时叫醒你;②非阻塞,返回给你个码字,告诉你数据没准备好,你可能还要再来问一遍。

    来点接地气的。下面这个程序很简单,不断从标准输入里读出数据,然后显示。

     33     while(1){
     37         ntowrite = read(0, buf, sizeof(buf));
     39         printf("ntowrite:%d
    ", ntowrite);
     40         sleep(2);
     42     };
    

    默认情况下,io是阻塞的,所以你会发现,程序会傻傻地卡在那里,等着输入:

    hon@hon:~/f2fs/share_aarch64/filemap$ ./block_test

    但是把上面的程序作如下修改,即通过fctnl将对stdin的读操作变成非阻塞的,结果就会变得大不一样。

     25     flag = fcntl(0, F_GETFL, 0);
     26     flag |= O_NONBLOCK;
     27     error = fcntl(0, F_SETFL, flag);
     28     if (error < 0)
     29         printf("std stdion to non-block fails
    ");
     30     while(1){ 
     34         ntowrite = read(0, buf, sizeof(buf));
     36         printf("ntowrite:%d
    ", ntowrite);
     37         sleep(2);
     38 
     39     };

    这次的结果是,程序不再傻等了,-1 就是操作系统给你的信息了:当前并没什么卵数据。

    hon@hon:~/f2fs/share_aarch64/filemap$ ./block_test
    ntowrite:-1
    ntowrite:-1
    ntowrite:-1
    ntowrite:-1
    ntowrite:-1
    ntowrite:-1
    .....

    上面就是不是对阻塞非阻塞有了个感性的认识呢?阻塞时,程序在 read 调用处傻傻等着,因为操作系统让你睡眠了;非阻塞时,操作系统不会让你等,有数据就返回数据,没数据就直白告诉你,但是总会返回。

  • 相关阅读:
    docker相关
    多线程
    设计模式
    ftp下载乱码问题
    Windows无法启动SQL server 代理服务(服务器)错误1067:进程意外终止
    Struts2 if标签
    Java项目编译时经常会出现不编译,或者报一些假性错误
    ajaxSubmit 上传文件 提示下载json处理
    MySQL中优化sql语句查询常用的30种方法
    mybatis 中的where标签
  • 原文地址:https://www.cnblogs.com/honpey/p/4694889.html
Copyright © 2011-2022 走看看