那些年让你迷惑的阻塞、非阻塞、异步、同步
点击上方“方志朋”,选择“置顶或者星标”
你的关注意义重大!
在IT圈混饭吃,不管你用什么编程语言、从事前端还是后端,阻塞、非阻塞、异步、同步这些概念,都需要清晰地掌握,否则,怎么与面试官谈笑风生(chui niu pi)?但是,掌握这些概念又不是非常容易,尤其对非科班出身的,更加困难。本文试图给出一个清晰简明但不失深刻的介绍,希望对大家有所帮助。
1、从I/O说起
这些概念之所以容易令人迷惑,在于很多人对I/O就没有清晰准确的理解,后面的理解自然不可能正确。我想用一个具体的例子来说明一下I/O。
设想自己是一个进程,就叫小进吧。小进需要接收一个输入,我们不管这个输入是从网络套接字来,还是键盘,鼠标来,输入的来源可以千千万万。但是,都必须由内核来帮小进完成,为啥内核这么霸道?因为计算机上运行的可不只是咱小进一个进程,还有很多进程。这些进程兄弟也可能需要从这些输入设备接收输入,没有内核居中协调,岂不是乱套。
从小进的角度看,内核帮助它完成输入,其实包括三个步骤:
1、内核替小进接收好数据,这些数据暂时存在内核的内存空间
2、内核将数据从自己的内存空间复制到小进的内存空间
3、告诉小进,输入数据来了,赶快读吧
这三步看似挺简单,其实在具体实现时,有很多地方需要考虑:
0、小进如何告诉内核自己要接收一个输入?
1、内核接到小进的请求,替小进接收好数据这段时间, 小进咋办?
2、内核在将数据复制到小进的内存空间这段时间,小进咋办?
3、到底什么时候告诉小进数据准备好了,是在内核接收好数据之后就告诉小进,还是在将数据复制到小进的内存空间之后再告诉他?
4、内核以什么样的方式告诉小进,数据准备好了?
2、阻塞式I/O模型
对上面5个问题,最简单的解决方案就是阻塞式I/O模型,它的过程是这样的:
小进:内核内核,我要接收一个键盘输入,快点帮我完成!
内核:好咧!biubiu!一个阻塞丢给小进,小进顿时石化,就像被孙悟空点了定一样。
就这样,小进在石化中,时间一点点流逝。终于,内核收到了数据。
内核:数据终于来了,我要开干了!duang duang duang,先把数据存在自己的内核空间,然后又复制到小进的用户空间。
内核:biubiu!一个解除阻塞丢给小进,小进瞬间复活,小进的记忆还是停留在让内核帮他接收输入时。
小进:哇!内核真靠谱,数据已经有了!干活去!
我们可以看到,小进发出接收输入的请求给内核开始,就处于阻塞状态,直到内核将数据复制到小进的用户空间,小进才解除阻塞。
3、非阻塞式I/O
小进发现,阻塞式I/O中,自己总要被阻塞好久,好不爽啊,于是小进改用了非阻塞式I/O,其过程是这样的:
小进:内核内核,我要接收一个输入,赶紧帮我看看,数据到了没有,先说好,不要阻塞我。
内核:查看了一下自己的内核空间,没有发现数据,于是迅速告诉小进,没有呢!并继续帮小进等着数据。
如此这样,小进不断地问内核,终于,过了一段时间,小进再一次询问时,内核往自己的空间中一查,呦!数据来了,不胜其烦的内核迅速告诉小进,数据好了!
小进:快给我!
内核:biu!一个阻塞丢给小进,悲催的小进还是石化了!
内核赶紧将自己空间的输入数据复制到小进的用户空间,复制好后。
内核:biu!一个非阻塞丢给小进,小进立马复活
小进:哇!数据来了,啥也不说,干活!
我们看到,所谓的非阻塞I/O,其实在内核将数据从内核空间复制到小进的用户空间时,小进还是被阻塞的。
4、信号驱动式I/O
非阻塞I/O中,小进不停地问内核,数据好了没有啊,内核感觉太烦了,于是想出一个好办法。
内核告诉小进,本内核升级了,如果想要我替你接收输入,请先注册一个信号处理函数,等数据准备好时,我会发信号给你。于是,现在的流程是这样的:
小进:注册信号处理函数,告诉内核,自己要接收一个输入,然后继续干活!
内核:收到函数,开始执行数据接收
接收完成时,给小进发送信号,信号处理函数收到信号,开始向内核发送读数据请求
内核:biu!阻塞了小进,并把数据从内核空间复制到小进的用户空间。
内核:biu!解除了阻塞
小进:哇!数据来了!啥也不说,干活去!
5、异步I/O
上面的三种I/O解决方案中,小进都被阻塞了,只不过是阻塞时间长短不一样,第一种方案中小进被阻塞的时间长一些,在内核接收数据以及将数据复制到小进的用户空间时,都被阻塞。
第二、第三种方案中,只在内核将数据从内核空间复制到小进的用户空间时,小进才被阻塞。
我们现在说的异步I/O,目的就是让小进绝对不被阻塞。其过程是这样的:
小进:内核内核,我要接收一个输入,弄好了告诉我。同时将一个信号和信号处理函数告诉内核,然后继续干自己的活了。
内核:得了您嘞,您先忙。
一直到内核接收到数据并将数据从内核空间复制到小进的用户空间后,内核才给小进发送信号。小进在信号处理函数中可以直接处理数据。
6、那啥是同步呢?
一句话,凡是让小进阻塞(不管长短)的I/O方案都是同步I/O。也就是说,阻塞、非阻塞、信号驱动式都是同步I/O。
7、无总结,不进步
上面,我们从完成输入时,进程与内核的交互方式的角度分析了不同的I/O解决方案,在这个过程中,解释清楚了阻塞、非阻塞、同步、异步的概念。
作者:milter 链接: https://www.jianshu.com/p/3d603166f54d
-更多文章-
限流降级神器-哨兵(sentinel)原理分析
Docker入门与实践
一张图看懂JVM
详解JVM内存管理与垃圾回收机制1 - 内存管理
详解JVM内存管理与垃圾回收机制2 - 何为垃圾
消息队列之 RabbitMQ
如何搭建自己的个人博客
我必须得告诉大家的MySQL优化原理
FeignClient源码深度解析
科普:String hashCode 方法为什么选择数字31作为乘子
分布式之消息队列复习精讲
-关注我-
那些年让你迷惑的阻塞、非阻塞、异步、同步相关推荐
- 同步/异步与阻塞/非阻塞的区别
这两组概念常常让人迷惑,因为它们都是涉及到IO处理,同时又有着一些相类似的地方. 首先来解释同步和 异步的概念,这两个概念与消息的通知机制有关. 举个 例子,比如我去银行办理业务,可能选择排队等候,也 ...
- 同步/异步 阻塞/非阻塞区别
我喜欢用自己的语言通过联系现实生活中的一些现象解释一些概念,当我能做到这一点时,说明我已经理解了这个概念.今天要解释的概念是:同步/异步与阻塞/非阻塞的区别. 这两组概念常常让人迷惑,因为它们都是涉及 ...
- 怎样理解阻塞非阻塞与同步异步的区别
怎样理解阻塞非阻塞与同步异步的区别? 发现很多人对这两个概念往往混为一谈 6 条评论 分享 按投票排序 按时间排序 47 个回答 605赞同 反对,不会显示你的姓名 卢毅 ,Lyft full-sta ...
- 异步通知是什么意思_一次相亲经历,我彻底搞懂了阻塞非阻塞、同步异步
看到标题,可能你会想,相亲跟阻塞/非阻塞,同步/异步有啥关系,这个逗b不知道在想什么东西.不要急,且听我慢慢道来 年纪大了,一回家七大姑八大姨就各种催婚,都说要给我介绍女朋友.这不,刚刚门口,我的大姨 ...
- 15分钟读懂进程线程、同步异步、阻塞非阻塞、并发并行,太实用了!
作者:Martin cnblogs.com/mhq-martin/p/9035640.html 基本概念 1 进程和线程 进程(Process): 是Windows系统中的一个基本概念,它包含着一个运 ...
- 迄今为止把同步/异步/阻塞/非阻塞/BIO/NIO/AIO讲的这么清楚的好文章(快快珍藏)...
常规的误区 假设有一个展示用户详情的需求,分两步,先调用一个HTTP接口拿到详情数据,然后使用适合的视图展示详情数据. 如果网速很慢,代码发起一个HTTP请求后,就卡住不动了,直到十几秒后才拿到HTT ...
- 同步 异步 阻塞 非阻塞概念区分
老张爱喝茶,废话不说,煮开水. 提前剧透一下:同步和非同步主要用来形容被调用线程,阻塞非阻塞用来形容主线程的. 出场人物:老张(主线程),水壶(被调用线程)两把(普通水壶,简称水壶:会响的水壶,简称响 ...
- 阻塞/非阻塞与同步/异步的区别
阻塞,非阻塞 同步,异步 阻塞与非阻塞最大的区别是调用方一直等待还是先去处理别的事情. 同步与异步最大的区别就是被调用方返回结果之前的这段时间内,调用方是否一直等待. 那么阻塞和同步,非阻塞和异步是一 ...
- 【面试】迄今为止把同步/异步/阻塞/非阻塞/BIO/NIO/AIO讲的这么清楚的好文章(快快珍藏)...
网上有很多讲同步/异步/阻塞/非阻塞/BIO/NIO/AIO的文章,但是都没有达到我的心里预期,于是自己写一篇出来. 常规的误区 假设有一个展示用户详情的需求,分两步,先调用一个HTTP接口拿到详情数 ...
- Socket 同步/异步 与阻塞/非阻塞区别
2019独角兽企业重金招聘Python工程师标准>>> 在网上看了很多答案,也没找到合适的,也许本文也不是合适答案:) 同步和异步关注的是消息通信机制,而阻塞非阻塞关注的是程序在等待 ...
最新文章
- 第一次全面揭示世界软件巨人微软致胜的技术奥秘
- 现在有T1、T2、T3三个线程,你怎样保证T2在T1执行完后执行,T3在T2执行完后执行?...
- WPF:下拉列表的简单实现
- mysql binlog 多少,MySQL binlog后面的编号最大是多大?
- UVa 10047,独轮车
- 第12章:Linux服务管理
- ML之ME/LF:机器学习中的模型评估指标/损失函数(连续型/离散型)的简介、损失函数/代价函数/目标函数之间区别、案例应用之详细攻略
- html5计数器,CSS 计数器(counter)
- 在文件中读取列表功能
- c 怎么配置oracle,cjdbc入门配置oracle
- 【Kafka】kafka消费报错 no brokers found in zk
- [转]《精通Javascript》笔记:第六章(事件)
- Hive里的分区、分桶、视图和索引再谈
- 仿微信选项卡主页面创建
- java面试题:重写和重载的区别——详解
- 在选用矿物质防火电缆的时候应该注意什么?
- 控制 input 输入框不能输入中文,即不能在输入框中使用输入法
- 中国境内哪个chatGPT最好用
- 20年3月27日,Github被攻击。我的GitPage博客也挂了,紧急修复之路,也教会你搭建 Jekyll 博客!
- linux文件中插入多行技巧