码迷,mamicode.com
首页 > 其他好文 > 详细

阻塞与非阻塞IO step by step

时间:2015-08-02 00:54:05      阅读:130      评论:0      收藏:0      [点我收藏+]

标签:

谈到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\n", 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\n");
 30     while(1){ 
 34         ntowrite = read(0, buf, sizeof(buf));
 36         printf("ntowrite:%d\n", 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 调用处傻傻等着,因为操作系统让你睡眠了;非阻塞时,操作系统不会让你等,有数据就返回数据,没数据就直白告诉你,但是总会返回。

阻塞与非阻塞IO step by step

标签:

原文地址:http://www.cnblogs.com/honpey/p/4694889.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!