阻塞与非阻塞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\n", ntowrite);
 40         sleep(2);
 42     };

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

[email protected]:~/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 就是操作系统给你的信息了:当前并没什么卵数据。

[email protected]:~/f2fs/share_aarch64/filemap$ ./block_test
ntowrite:-1
ntowrite:-1
ntowrite:-1
ntowrite:-1
ntowrite:-1
ntowrite:-1.....

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

时间: 2024-10-14 01:12:26

阻塞与非阻塞IO step by step的相关文章

Java中的阻塞和非阻塞IO包各自的优劣思考

NIO 设计背后的基石:反应器模式,用于事件多路分离和分派的体系结构模式. 反应器(Reactor):用于事件多路分离和分派的体系结构模式 通常的,对一个文件描述符指定的文件或设备, 有两种工作方式: 阻塞 与非阻塞 .所谓阻塞方式的意思是指, 当试图对该文件描述符进行读写时, 如果当时没有东西可读,或者暂时不可写, 程序就进入等待 状态, 直到有东西可读或者可写为止.而对于非阻塞状态, 如果没有东西可读, 或者不可写, 读写函数马上返回, 而不会等待 . 一种常用做法是:每建立一个Socket

阻塞与非阻塞IO -- 网络编程随想

阻塞和非阻塞IO 阻塞IO指当进行IO操作时, 如果IO操作无法立即完成,当前线程进入阻塞状态,直到IO操作完成,IO函数返回. 非阻塞IO指当进行IO操作时,如果IO操作无法立即完成,IO函数立即返回,线程不会阻塞. 写与读操作对阻塞与非阻塞IO的语义 写操作,只有完成所有指定数据的写入时,写操作才算完成. 读操作,只要能读取到数据,读操作就算完成. 阻塞IO 写操作.len 为指定写入的数据量. 如果只写入部分数据,IO函数会阻塞直至写入数据或发生错误才返回. 以soket的send()为例

IO模式——同步(阻塞、非阻塞)、异步

不少人把同步.异步.阻塞.非阻塞放到一起讨论,很多时候难以区分. 这里从根上剖析下该怎么看待这几个概念. 首先,异步和同步是相对的,而同步情况下又有阻塞和非阻塞之分. 异步很容易理解.当用户程序需要进行IO的时候,发出IO请求,然后就立刻返回,可以继续做其它事情. 例如,从网络收包,当包抵达后放到内核某个缓存区,并且从内核空间放置到程序需要的用户空间后(一种是直接复制,比较费资源:一种是映射mmap),通知程序,程序之后就可以处理数据了. 这是最理想的模式,CPU干活效率最高. 同步情况则是,当

[Z] IO - 同步,异步,阻塞,非阻塞 (亡羊补牢篇)

原文链接:http://blog.csdn.net/historyasamirror/article/details/5778378 当你发现自己最受欢迎的一篇blog其实大错特错时,这绝对不是一件让人愉悦的事.<IO - 同步,异步,阻塞,非阻塞 >是我在开始学习epoll和libevent的时候写的,主要的思路来自于文中的那篇link .写完之后发现很多人都很喜欢,我还是非常开心的,也说明这个问题确实困扰了很多人.随着学习的深入,渐渐的感觉原来的理解有些偏差,但是还是没引起自己的重视,觉着

IO中同步异步,阻塞与非阻塞 -- 原理篇

再补一篇高手写的理论分析,便于更深刻理解 转自:http://blog.csdn.net/historyasamirror/article/details/5778378 ============================================================= 同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这个问题其实不同的人给出的答

网络IO之阻塞、非阻塞、同步、异步总结

1.前言 在网络编程中,阻塞.非阻塞.同步.异步经常被提到.unix网络编程第一卷第六章专门讨论五种不同的IO模型,Stevens讲的非常详细,我记得去年看第一遍时候,似懂非懂,没有深入理解.网上有详细的分析:http://blog.csdn.net/historyasamirror/article/details/5778378.我结合网上博客和书总结一下,加以区别,加深理解. 2.数据流向 网络IO操作实际过程涉及到内核和调用这个IO操作的进程.以read为例,read的具体操作分为以下两个

简述linux同步与异步、阻塞与非阻塞概念以及五种IO模型

1.概念剖析 相信很多从事linux后台开发工作的都接触过同步&异步.阻塞&非阻塞这样的概念,也相信都曾经产生过误解,比如认为同步就是阻塞.异步就是非阻塞,下面我们先剖析下这几个概念分别是什么含义. 同步:所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回.也就是必须一件一件事做,等前一件做完了才能做下一件事. 例如普通B/S模式(同步):提交请求->等待服务器处理->处理完毕返回 这个期间客户端浏览器不能干任何事 异步:异步的概念和同步相对.当一个异步过程

高级IO,阻塞于非阻塞

1.1.非阻塞IO 1.阻塞与非阻塞 (1)阻塞:就是当前的函数要执行的话,需要某些条件,但是没有达到,就被阻塞住,内核挂起,当前进程暂停.CPU被拿去运行别的进程了.比如父进程执行wait这个阻塞函数,等待子进程结束后,去回收子进程剩余的8KB内存资源,如果这个时候子进程没有结束,父进程的wait就会被阻塞,因为条件没有达到,这个时候父进程就暂停了,内核就挂起了,CPU的时间就去执行别的进程了,不在父进程这里耗了,当子进程结束的时候,OS会给子进程的父进程发送一个SIGCHILD信号,这时父进

Linux下阻塞与非阻塞IO

阻塞:顾名思义,就是指在执行设备操作时若不能获得资源则挂起操作,直到满足可操作的条件后再进行操作,被挂起的进程进入休眠状态,被从调度器的运行队列移走,直到等待的条件满足. 非阻塞:就是反过来,进程在不能进行设备操作时并不挂起,它或者放弃,或者不停的查询,直到可以进行位置. Socket编程中,阻塞与非阻塞的区别: 阻塞:一般的I/O操作可以在新建的流中运用.在服务器回应前它等待客户端发送一个空白的行.当会话结束时,服务器关闭流和客户端socket. 如果在队列中没有请示将会出现什么情况呢?那个方