浅析同步/异步和阻塞/非阻塞的区别

首先,我需要特别说明一下
同步、异步 和 阻塞、非阻塞 不是一件事情,不是一个事物;

我也是前不久看见我的一些群里面的一些群友提出的这个问题,我才想着写这么一篇文章出来

首先

同步/异步

同步异步是什么呢,其实就是程序数据的告知机制

何谓数据告知机制呢,其实就是我执行一个程序,而这个程序如何返回我数据的机制,就叫告知机制

举个栗子

同步

所谓同步呢,就是客户端发起调用后,程序处理消息,必须等处理完才直接返回数据,没处理完之前是不返回的,客户端必须主动等待数据;

举个栗子:我们一行人排队,如果你擅自走开了,别人就会排上来,你就功亏一篑,你必须等到完成这个队列,你才能算完成;

而异步是如何呢;

异步

异步呢,就是客户端发起调用后,程序直接返回,但是并没有立即返回数据,等处理完后,通过通知或者回调函数来通知客户端,客户端被动的去接收数据。

同样的举个栗子:还是一行人排队,但是这个时候我们有个号码牌的功能,根据号码牌来排队,这个时候,你可以去吃个泡面啊。啥的,等叫到你时,就是你可以完成任务了;

其次

阻塞/非阻塞

这个呢,他就不是消息机制了,而是程序等待消息时的状态,说的明白点呢,就是线程挂起机制

阻塞

阻塞呢,就是执行的程序的结果返回给执行者之前,该执行线程会被挂起,不释放CPU执行权,线程不能做其它事情,只能等待,只有等到程序的结果返回了,才能继续往下执行;

再来举个栗子:就拿同步的栗子来讲,你在排队时不能出队列是吧,阻塞呢,就是不能出队列的同时,你其他啥事情都不能干,只能排着;

非阻塞

而非阻塞呢,就是在没有获取到执行程序的结果时,不是一直等待,线程可以往下执行,干其他事情,如果是同步的,通过轮询的方式检查有没有调用结果返回,如果是异步的,会通知回调。

还是那个栗子:就拿同步的栗子来讲,你在排队时不能出队列是吧,阻塞呢,不是啥都不能干吗,非阻塞就是我拿起手机玩个游戏啊,看个电影啊啥的,干着其他事情,就是非阻塞

所以呢,从根本上讲I/O操作分为两部分,客户端的程序调用和内核层的I/O操作

所以异步/同步的是指客户端的程序调用;
阻塞/非阻塞是指内核的I/O调用的模式。

同步阻塞:是用户层的读或写的请求转换成内核的I/O请求,直到I/O请求阻塞(阻塞,读到数据返回,读不到一直等待)结束,才结束用户层的请求。
同步非阻塞(NIO):是用户层的读或写的请求转换成内核的I/O请求,用户层同步,内核I/O非阻塞(读到返回字节,读不到返回-1)。
异步阻塞:把I/O读取细化为订阅I/O事件,实际I/O读写,在“订阅I/O事件”事件部分会主动让出CPU直到事件发生,内核部分I/O请求阻塞。
异步非阻塞(AIO):用户层的读或写的请求转换成内核的I/O请求,用户层异步,内核I/O非阻塞。

而这四个直接拿栗子说话吧:

同步阻塞:我没有号码牌排队,并且不做任何其他事情;
同步非阻塞(NIO):我没有号码牌排队,并且做了其他事情;
异步阻塞:我有号码牌排队,并且不做任何其他事情;
异步非阻塞(AIO):我有号码牌排队,并且做了其他事情;

本文为ctexthuang原创文章,转载请注明来自ctexthuang_blog

tag(s): none
show comments · back · home
Edit with markdown
召唤看板娘