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
I/O模型: 阻塞、非阻塞、I/O复用、同步、异步的更多相关文章
- Python番外之 阻塞非阻塞,同步与异步,i/o模型
1. 概念理解 在进行网络编程时,我们常常见到同步(Sync)/异步(Async),阻塞(Block)/非阻塞(Unblock)四种调用方式: 同步/异步主要针对C端: 同步: 所谓同步,就 ...
- linux基础编程:IO模型:阻塞/非阻塞/IO复用 同步/异步 Select/Epoll/AIO(转载)
IO概念 Linux的内核将所有外部设备都可以看做一个文件来操作.那么我们对与外部设备的操作都可以看做对文件进行操作.我们对一个文件的读写,都通过调用内核提供的系统调用:内核给我们返回一个file ...
- (转)同步异步,阻塞非阻塞 和nginx的IO模型
同步异步,阻塞非阻塞 和nginx的IO模型 原文:https://www.cnblogs.com/wxl-dede/p/5134636.html 同步与异步 同步和异步关注的是消息通信机制 (sy ...
- Python之阻塞IO模型与非阻塞IO模型
Python之阻塞IO模型与非阻塞IO模型 IO模型 1 阻塞IO: 全程阻塞 2 非阻塞IO: 发送多次系统调用: 优点:wait for data时无阻塞 缺点:1 系统调用太多 2 数据不是实时 ...
- python并发编程之IO模型 同步 异步 阻塞 非阻塞
IO浅谈 首先 我们在谈及IO模型的时候,就必须要引入一个“操作系统”级别的调度者-系统内核(kernel),而阻塞非阻塞是跟进程/线程严密相关的,而进程/线程又是依赖于操作系统存在的,所以自然不能脱 ...
- 深入了解几种IO模型(阻塞非阻塞,同步异步)
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/zk3326312/article/details/79400805一般来说,Linux下系统IO主要 ...
- 哪5种IO模型?什么是select/poll/epoll?同步异步阻塞非阻塞有啥区别?全在这讲明白了!
系统中有哪5种IO模型?什么是 select/poll/epoll?同步异步阻塞非阻塞有啥区别? 本文地址http://yangjianyong.cn/?p=84转载无需经过作者本人授权 先解开第一个 ...
- 🍛 餐厅吃饭版理解 IO 模型:阻塞 / 非阻塞 / IO 复用 / 信号驱动 / 异步
IO 概念 一个基本的 IO,它会涉及到两个系统对象,一个是调用这个 IO 的进程对象,另一个就是系统内核 (kernel).当一个 read 操作发生时,它会经历两个阶段: 通过 read 系统调用 ...
- 异步|同步&阻塞|非阻塞
异步|同步:区别在于发出一个功能调用时,是否马上得到返回结果 阻塞|非阻塞:区别在于调用结果返回之前,当前线程是否挂起 node.js:单线程.异步非阻塞模型 单线程与异步不矛盾,与并发是矛盾的 ht ...
- I/O阻塞非阻塞,同步异步
http://www.cnblogs.com/luotianshuai/p/5098408.html "阻塞"与"非阻塞"与"同步"与&qu ...
随机推荐
- 【Java爬虫】爬取南通大学教务处成绩
没使用自动登录,所以获取是比较麻烦.. 1.http://jwgl.ntu.edu.cn/cjcx 进入官网,进行账号密码登录 2.点击全部成绩查询(也一定要点进去,不然cookie不会返回值) ...
- LA3516 Exploring Pyramids
Exploring Pyramids 题目大意:给定一个欧拉序列(即每经过一个点,把这个点加入序列),问有多少种对应的多叉树 序列与树构造对应问题,考虑区间DP dp[i][j]表示序列i...j对应 ...
- 微信网页授权demo2
1.在微信公众号请求用户网页授权之前,开发者需要先到公众平台官网中的“开发 - 接口权限 - 网页服务 - 网页帐号 - 网页授权获取用户基本信息”的配置选项中,修改授权回调域名.请注意,这里填写的是 ...
- stream分组
1.根据集合元素中的一个属性值分组 Person p1 = new Person("张三", new BigDecimal("10.0"));Person p2 ...
- 整体二分(模板) 求区间第k小
整体二分,将询问与初值一起放入一个结构体里,然后每次二分判断询问在哪边,树状数组维护,时间复杂度O((n+Q)lognlogMAX_a[i] 代码 #include<iostream> # ...
- 【JZOJ5338】【NOIP2017提高A组模拟8.25】影子 点分治?/ 排序
题面 65 看到路径问题,就想到了套路:点分治. 对于一个分治中心,先把在其子树的结点的sum和mn求出来,分别表示该节点到分治中心的边权和和点权最小值. 然后把mn离散化,并插入权值线段树中,以su ...
- SSH 框架controller向jsp传递List jsp中使用el表达式获取
mvc可以使用ModelAndViev传递数据选择跳转的视图 controller中的代码, 把一个模拟的表单studentListSimulate传给ModelAndView @RequestMap ...
- 2019.9.28 csp-s模拟测试54 反思总结
咕咕咕的冲动如此强烈x T1x: 看完题目想了想,感觉把gcd不为1的强行放在一组,看作一个连通块,最后考虑连通块之间的组合方式就可以了. 然后维护这个连通块可以写并查集可以连边跑dfs怎么着都行… ...
- 洛谷P4145 上帝造题的七分钟2 / 花神游历各国(重题:洛谷SP2713 GSS4 - Can you answer these queries IV)
题目背景 XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. 题目描述 "第一分钟,X说,要有数列,于是便给定了一个正整数数列. 第二分钟,L说,要能修改,于是便有了对一段 ...
- Vue--vue中的组件、组件绑定事件和数据、私有组件、子组件,父子组件参数互传
一.公有组件以及组件的使用和特点 <!DOCTYPE html> <html lang="en"> <head> <meta charse ...