【转载】迄今为止把同步/异步/阻塞/非阻塞/BIO/NIO/AIO讲的这么清楚的好文章(快快珍藏)
原文链接:https://www.cnblogs.com/lixinjie/p/10811219.html
常规的误区
假设有一个展示用户详情的需求,分两步,先调用一个HTTP接口拿到详情数据,然后使用适合的视图展示详情数据。
如果网速很慢,代码发起一个HTTP请求后,就卡住不动了,直到十几秒后才拿到HTTP响应,然后继续往下执行。
这个时候你问别人,刚刚代码发起的这个请求是不是一个同步请求,对方一定回答是。这是对的,它确实是。
但你要问它为什么是呢?对方一定是这样回答的,“因为发起请求后,代码就卡住不动了,直到拿到响应后才可以继续往下执行”。
我相信很多人也都是这样认为的,其实这是不对的,是把因果关系搞反了:
不是因为代码卡住不动了才叫同步请求,而是因为它是同步请求所以代码才卡住不动了。
至于为什么能卡住不动,这是由操作系统和CPU决定的:
因为内核空间里的对应函数会卡住不动,造成用户空间发起的系统调用卡住不动,继而使程序里的用户代码卡住不动了。
因此卡住不动了只是同步请求的一个副作用,并不能用它来定义同步请求,那该如何定义呢?
同步和异步
所谓同步,指的是协同步调。既然叫协同,所以至少要有2个以上的事物存在。协同的结果就是:
多个事物不能同时进行,必须一个一个的来,上一个事物结束后,下一个事物才开始。
那当一个事物正在进行时,其它事物都在干嘛呢?
严格来讲这个并没有要求,但一般都是处于一种“等待”的状态,因为通常后面事物的正常进行都需要依赖前面事物的结果或前面事物正在使用的资源。
因此,可以认为,同步更希望关注的是从宏观整体来看,多个事物是一种逐个逐个的串行化关系,绝对不会出现交叉的情况。
所以,自然也不太会去关注某个瞬间某个具体事物是处于一个什么状态。
把这个理论应用的出神入化的非“排队”莫属。凡是在资源少需求多的场景下都会用到排队。
比如排队买火车票这件事:
其实售票大厅更在意的是旅客一个一个的到窗口去买票,因为一次只能卖一张票。
即使大家一窝蜂的都围上去,还是一次只能卖一张票,何必呢?挤在一起又不安全。
只是有些人素质太差,非要往上挤,售票大厅迫不得已,采用排队这种形式来达到自己的目的,即一个一个的买票。
至于每个旅客排队时的状态,是看手机呀还是说话呀,根本不用去在意。
除了这种由于资源导致的同步外,还存在一种由于逻辑上的先后顺序导致的同步。
比如,先更新代码,然后再编译,接着再打包。这些操作由于后一步要使用上一步的结果,所以只能按照这种顺序一个一个的执行。
关于同步还需知道两个小的点:
一是范围,并不需要在全局范围内都去同步,只需要在某些关键的点执行同步即可。
比如食堂只有一个卖饭窗口,肯定是同步的,一个人买完,下一个人再买。但吃饭的时候也是一个人吃完,下一个人才开始吃吗?当然不是啦。
二是粒度,并不是只有大粒度的事物才有同步,小粒度的事物也有同步。
只不过小粒度的事物同步通常是天然支持的,而大粒度的事物同步往往需要手工处理。
比如两个线程的同步就需要手工处理,但一个线程里的两个语句天然就是同步的。
所谓异步,就是步调各异。既然是各异,那就是都不相同。所以结果就是:
多个事物可以你进行你的、我进行我的,谁都不用管谁,所有的事物都在同时进行中。
一言以蔽之,同步就是多个事物不能同时开工,异步就是多个事物可以同时开工。
注:一定要去体会“多个事物”,多个线程是多个事物,多个方法是多个事物,多个语句是多个事物,多个CPU指令是多个事物。等等等等。
阻塞和非阻塞
所谓阻塞,指的是阻碍堵塞。它的本意可以理解为由于遇到了障碍而造成的动弹不得。
所谓非阻塞,自然是和阻塞相对,可以理解为由于没有遇到障碍而继续畅通无阻。
对这两个词最好的诠释就是,当今中国一大交通难题,堵车:
汽车可以正常通行时,就是非阻塞。一旦堵上了,全部趴窝,一动不动,就是阻塞。
因此阻塞关注的是不能动,非阻塞关注的是可以动。
不能动的结果就是只能等待,可以动的结果就是继续前行。
因此和阻塞搭配的词一定是等待,和非阻塞搭配的词一定是进行。
回到程序里,阻塞同样意味着停下来等待,非阻塞表明可以继续向下执行。
阻塞和等待
等待只是阻塞的一个副作用而已,表明随着时间的流逝,没有任何有意义的事物发生或进行。
阻塞的真正含义是你关心的事物由于某些原因无法继续进行,因此让你等待。但没必要干等,你可以做一些其它无关的事物,因为这并不影响你对相关事物的等待。
在堵车时,你可以干等。也可以玩手机、和别人聊天,或者打牌、甚至先去吃饭都行。因为这些事物并不影响你对堵车的等待。不过你的车必须呆在原地。
在计算机里,是没有人这么灵活的,一般在阻塞时,选在干等,因为这最容易实现,只需要挂起线程,让出CPU即可。在条件满足时,会重新调度该线程。
两两组合
所谓同步/异步,关注的是能不能同时开工。
所谓阻塞/非阻塞,关注的是能不能动。
通过推理进行组合:
同步阻塞,不能同时开工,也不能动。只有一条小道,一次只能过一辆车,可悲的是还TMD的堵上了。
同步非阻塞,不能同时开工,但可以动。只有一条小道,一次只能过一辆车,幸运的是可以正常通行。
异步阻塞,可以同时开工,但不可以动。有多条路,每条路都可以跑车,可气的是全都TMD的堵上了。
异步非阻塞,可以工时开工,也可以动。有多条路,每条路都可以跑车,很爽的是全都可以正常通行。
是不是很容易理解啊。其实它们的关注点是不同的,只要搞明白了这点,组合起来也不是事儿。
回到程序里,把它们和线程关联起来:
同步阻塞,相当于一个线程在等待。
同步非阻塞,相当于一个线程在正常运行。
异步阻塞,相当于多个线程都在等待。
异步非阻塞,相当于多个线程都在正常运行。
I/O
IO指的就是读入/写出数据的过程,和等待读入/写出数据的过程。一旦拿到数据后就变成了数据操作了,就不是IO了。
拿网络IO来说,等待的过程就是数据从网络到网卡再到内核空间。读写的过程就是内核空间和用户空间的相互拷贝。
所以IO就包括两个过程,一个是等待数据的过程,一个是读写(拷贝)数据的过程。而且还要明白,一定不能包括操作数据的过程。
阻塞IO和非阻塞IO
应用程序都是运行在用户空间的,所以它们能操作的数据也都在用户空间。按照这样子来理解,只要数据没有到达用户空间,用户线程就操作不了。
如果此时用户线程已经参与,那它一定会被阻塞在IO上。这就是常说的阻塞IO。用户线程被阻塞在等待数据上或拷贝数据上。
非阻塞IO就是用户线程不参与以上两个过程,即数据已经拷贝到用户空间后,才去通知用户线程,一上来就可以直接操作数据了。
用户线程没有因为IO的事情出现阻塞,这就是常说的非阻塞IO。
同步IO和同步阻塞IO
按照上文中对同步的理解,同步IO是指发起IO请求后,必须拿到IO的数据才可以继续执行。
按照程序的表现形式又分为两种:
在等待数据的过程中,和拷贝数据的过程中,线程都在阻塞,这就是同步阻塞IO。
在等待数据的过程中,线程采用死循环式轮询,在拷贝数据的过程中,线程在阻塞,这其实还是同步阻塞IO。
网上很多文章把第二种归为同步非阻塞IO,这肯定是错误的,它一定是阻塞IO,因为拷贝数据的过程,线程是阻塞的。
严格来讲,在IO的概念上,同步和非阻塞是不可能搭配的,因为它们是一对相悖的概念。
同步IO意味着必须拿到IO的数据,才可以继续执行。因为后续操作依赖IO数据,所以它必须是阻塞的。
非阻塞IO意味着发起IO请求后,可以继续往下执行。说明后续执行不依赖于IO数据,所以它肯定不是同步的。
因此,在IO上,同步和非阻塞是互斥的,所以不存在同步非阻塞IO。但同步非阻塞是存在的,那不叫IO,叫操作数据了。
所以,同步IO一定是阻塞IO,同步IO也就是同步阻塞IO。
异步IO和异步阻塞/非阻塞IO
按照上文中对异步的理解,异步IO是指发起IO请求后,不用拿到IO的数据就可以继续执行。
用户线程的继续执行,和操作系统准备IO数据的过程是同时进行的,因此才叫做异步IO。
按照IO数据的两个过程,又可以分为两种:
在等待数据的过程中,用户线程继续执行,在拷贝数据的过程中,线程在阻塞,这就是异步阻塞IO。
在等待数据的过程中,和拷贝数据的过程中,用户线程都在继续执行,这就是异步非阻塞IO。
第一种情况是,用户线程没有参与数据等待的过程,所以它是异步的。但用户线程参与了数据拷贝的过程,所以它又是阻塞的。合起来就是异步阻塞IO。
第二种情况是,用户线程既没有参与等待过程也没有参与拷贝过程,所以它是异步的。当它接到通知时,数据已经准备好了,它没有因为IO数据而阻塞过,所以它又是非阻塞的。合起来就是异步非阻塞IO。
PS:聪明的你或许发现了我没有提多路复用IO,因为它值得专门撰文一篇。
【转载】迄今为止把同步/异步/阻塞/非阻塞/BIO/NIO/AIO讲的这么清楚的好文章(快快珍藏)的更多相关文章
- 【面试】迄今为止把同步/异步/阻塞/非阻塞/BIO/NIO/AIO讲的这么清楚的好文章(快快珍藏)
常规的误区 假设有一个展示用户详情的需求,分两步,先调用一个HTTP接口拿到详情数据,然后使用适合的视图展示详情数据. 如果网速很慢,代码发起一个HTTP请求后,就卡住不动了,直到十几秒后才拿到HTT ...
- 迄今为止把同步/异步/阻塞/非阻塞/BIO/NIO/AIO讲的这么清楚的好文章(快快珍藏)
常规的误区 假设有一个展示用户详情的需求,分两步,先调用一个HTTP接口拿到详情数据,然后使用适合的视图展示详情数据. 如果网速很慢,代码发起一个HTTP请求后,就卡住不动了,直到十几秒后才拿到HTT ...
- 【转载】高性能IO设计 & Java NIO & 同步/异步 阻塞/非阻塞 Reactor/Proactor
开始准备看Java NIO的,这篇文章:http://xly1981.iteye.com/blog/1735862 里面提到了这篇文章 http://xmuzyq.iteye.com/blog/783 ...
- linux基础编程:IO模型:阻塞/非阻塞/IO复用 同步/异步 Select/Epoll/AIO(转载)
IO概念 Linux的内核将所有外部设备都可以看做一个文件来操作.那么我们对与外部设备的操作都可以看做对文件进行操作.我们对一个文件的读写,都通过调用内核提供的系统调用:内核给我们返回一个file ...
- 008. 阻塞&非阻塞、同步&异步
阻塞 非阻塞:关注的对象是调用者: 阻塞:调用者发起调用后,处于等待状态,直到该调用有返回: 非阻塞:调用者发起调用后,不需要等待返回,可以往下执行: 同步 异步: 关注的对象是被调用者: 同步:服 ...
- python并发编程之IO模型 同步 异步 阻塞 非阻塞
IO浅谈 首先 我们在谈及IO模型的时候,就必须要引入一个“操作系统”级别的调度者-系统内核(kernel),而阻塞非阻塞是跟进程/线程严密相关的,而进程/线程又是依赖于操作系统存在的,所以自然不能脱 ...
- 同步与异步,阻塞与非阻塞 bio,nio,aio
BIO.NIO和AIO的区别(简明版) 同步异步,阻塞非阻塞: https://www.zhihu.com/question/19732473 转载请注明原文地址:http://www.cnblo ...
- 深入了解几种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转载无需经过作者本人授权 先解开第一个 ...
随机推荐
- grpc的简单用例 (C++实现)
这个用例的逻辑很简单, 服务器运行一个管理个人信息的服务, 提供如下的四个服务: (1) 添加一个个人信息 注: 对应于Unary RPCs, 客户端发送单一消息给服务器, 服务器返回单一消息 (2) ...
- Oracle数据库 常用SQL
-- 查询所有数据 SELECT * FROM [TABLE_NAME]; -- 查询数据总量 SELECT COUNT(*) AS COUNT FROM [TABLE_NAME]; -- 清空表内所 ...
- DFS遍历拷贝所有子文件夹及目录列表 (Java版)
如题 注意,文件夹是不能拷贝的, 需要mkdir的 文件选择合适的流进行拷贝 main测试方法 /** * 主测试类,默认将D:\\base01 下的复制到D:\\base02 * @param ar ...
- #《你们都是魔鬼吗》第八次团队作业:第五天Alpha冲刺
<你们都是魔鬼吗>第八次团队作业:Alpha冲刺 项目 内容 这个作业属于哪个课程 任课教师博客主页链接 这个作业的要求在哪里 作业链接地址 团队名称 你们都是魔鬼吗 作业学习目标 完成最 ...
- java singleton(单例设计模式)
单例设计模式的主要作用是: 1.控制资源的使用,我们对资源使用线程同步来实现并发访问. 2.节约资源,我们对一个类只进行一个实例化进行全局的资源访问,节约了内存. 3.作为通信媒介,也是数据共享,可以 ...
- 第4课.vi编辑器
1.vi编辑器的配置 cd /etc/vim cp vimrc ~/.vimrc cd ~ gedit .vimrc 在.vimrc中加入如下内容: "关闭兼容功能 set nocompat ...
- Kibana<6.6.0代码执行漏洞复现
更多内容,欢迎关注微信公众号:信Yang安全,期待与您相遇. 使用docker快速部署环境docker pull kibana:6.5.4docker pull elasticsearch:6.5.4 ...
- Vim初学
实现G++编译 1,首先下载安装MinGW,下载地址在http://sourceforge.net/projects/mingw/.这个是边下载边安装的,下载完成即安装完成.我的安装目录是G:\Min ...
- GSS3 C - Can you answer these queries III
//在gss1的基础上加了修改操作,一样的做法,加一个modify函数就可以了 #include<iostream> #include<cstdio> #include< ...
- Strategic game(树形DP入门)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1054 题目大意:一棵树,要放置哨兵,要求最少放置多少哨兵能监视到所有的结点 题目分析: 放置哨兵无非两 ...