一个例子理解同步-异步、阻塞-非阻塞

在编程进阶中,往往很多程序员会碰到同步异步,还有阻塞与非阻塞,这些概念往往容易混淆,下面我将通过一个例子来详细说明他们之间的差别。

我们可以联想这样一个场景张三平时爱喝茶,现在他要去烧开水,即概括为:

张三,废话不多说,煮开水。

出场人物:张三,水壶两把(普通水壶,简称水壶;会响的水壶,简称响水壶)。

1 张三把水壶放到火上,立等水开。(同步阻塞)

张三觉得自己有点傻

2 张三把水壶放到火上,去客厅看电视,时不时去厨房看看水开没有。(同步非阻塞)

张三还是觉得自己有点傻,于是变高端了,买了把会响笛的那种水壶。水开之后,能大声发出嘀~~~~的噪音。

3 张三把响水壶放到火上,立等水开。(异步阻塞)

张三觉得这样傻等意义不大

4 张三把响水壶放到火上,去客厅看电视,水壶响之前不再去看它了,响了再去拿壶。(异步非阻塞)

张三觉得自己聪明了。

所谓同步异步,只是对于水壶而言。

普通水壶,同步;响水壶,异步。

虽然都能干活,但响水壶可以在自己完工之后,提示张三水开了。这是普通水壶所不能及的。

同步只能让调用者去轮询自己(情况2中),造成张三效率的低下。

所谓阻塞非阻塞,仅仅对于张三而言。

立等的张三,阻塞;看电视的张三,非阻塞。

情况1和情况3中张三就是阻塞的,媳妇喊他都不知道。虽然3中响水壶是异步的,可对于立等的张三没有太大的意义。所以一般异步是配合非阻塞使用的,这样才能发挥异步的效用。

总结:

同步,异步 --》被调用者是否拥有该功能

阻塞,非阻塞--》调用者是否拥有该功能

==========================================

总结:

A. 同步

所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回。

B. 异步

异步的概念和同步相对。

当一个异步过程调用发出后,调用者不会立刻得到结果。

实际处理这个调用的部件是在调用发出后,

通过状态、通知来通知调用者,或通过回调函数处理这个调用。

C. 三种返回结果途径

执行部件和调用者可以通过三种途径返回结果:

a. 状态、(轮询方式)

b. 通知、

c. 回调函数。

==========================================

A. 阻塞

阻塞调用是指调用结果返回之前,当前线程会被挂起。函数只有在得到结果之后才会返回。

有人也许会把阻塞调用和同步调用等同起来,实际上他是不同的。

对于同步调用来说,很多时候当前线程还是激活的,只是从逻辑上当前函数没有返回而已。

socket接收数据函数recv是一个阻塞调用的例子。

当socket工作在阻塞模式的时候, 如果没有数据的情况下调用该函数,则当前线程就会被挂起,直到有数据为止。

B. 非阻塞

非阻塞和阻塞的概念相对应,指在不能立刻得到结果之前,该函数不会阻塞当前线程,而会立刻返回。

C. 对象的阻塞模式和阻塞函数调用

对象是否处于阻塞模式和函数是不是阻塞调用有很强的相关性,但是并不是一一对应的。

阻塞对象上可以有非阻塞的调用方式,我们可以通过一定的API去轮询状态,

在适当的时候调用阻塞函数,就可以避免阻塞。

而对于非阻塞对象,调用特殊的函数也可以进入阻塞调用。函数select就是这样的一个例子。

猜你喜欢

转载自blog.csdn.net/longzhongxiaoniao/article/details/85310811
今日推荐