(通俗易懂)阻塞、非阻塞、同步、异步区别

我们在学习操作系统等计算机相关知识的时候,经常会见到阻塞、非阻塞、同步、异步这几个关键词。尤其是通过纸面资料学习,而不是自己动手实践的过程中更容易混淆这几个知识点。

最经典的错误观点:阻塞就是同步,非阻塞就是异步!

前面简单介绍过I/O多路复用(I/O多路转接)-CSDN博客多线程实现并发服务-CSDN博客多进程实现并发服务器-CSDN博客。这三者用涉及到的都是同步IO。

一次IO,两个阶段

我们把一次获取数据的过程,简单的划分为两个阶段:数据就绪(等待数据到达)和数据读写(处理数据)这两个过程。

先直接结论以通俗易懂的方式告诉你:

阻塞、非阻塞发生在数据就绪阶段,同步、异步发生在数据读写阶段。这句话咋一看,怪怪的,不够严谨,但接着往下看就能深入理解了。

引入一个生活中的例子,一只小猪肚子饿了,他现在需要到饭店吃饭。

第一种情况(阻塞态):

  • 猪猪肚子饿了,走进饭店,目的是填饱肚子。
  •  猪猪:老板,我要一碗猪脚饭。
  •  老板:好的,现在做,要稍等十分钟做好。
  • (猪猪乖乖坐在位置上等了10分钟)
  • 老板:饭做好啦,拿去吃吧。
  • 猪猪吭哧吭哧地吃了5分钟,填饱了肚子。

在这种情况中,老板在做饭的时候,猪猪什么事也没做,阻塞等待老板做饭。也就是对应着,数据就绪阶段阻塞了,没有处理其他事件。再看看非阻塞状态是怎样的。

第二种情况(非阻塞态):

  • 猪猪肚子饿了,走进饭店,目的是填饱肚子。
  • 猪猪:老板,我要一碗猪脚饭。
  • 老板:好的,现在做,要稍等一会。
  • 猪猪:好的,那我先去隔壁买杯奶茶吧。
  • (猪猪去买奶茶(做了别的事),每隔1分钟打电话问老板饭做好了没)
  • 老板:饭做好啦,回来吃吧。
  • 猪猪回到饭店吭哧吭哧地吃了5分钟,填饱了肚子。

以上两种情况很好地解释了什么是阻塞和非阻塞。总结一下就是在数据就绪阶段,如果进程或者线程能够去处理其他事情,而不是单纯地原地等待数据的到来那就是非阻塞,反之就是阻塞。

再来分析下同步和异步,前面介绍的以上两种情况都是同步,为什么呢?先告诉答案。

因为以上两种情况,对于猪猪饿了,目的是填饱肚子,在老板做好饭,把饭给到猪猪后,在猪猪填饱肚子地这个过程中,是由猪猪自己进食的,也就是猪猪还是花了自己的时间在进食上。如果老板能够在做好饭后直接一整碗直接塞进猪肚子里,再给猪猪一个信号:你要的饭我已经帮你塞进肚子里了,你自己慢慢消化吧。

第三种情况(异步):

  • 猪猪肚子饿了,走进饭店,目的是填饱肚子。
  • 猪猪:老板,我要一碗猪脚饭。
  • 老板:好的,现在做,要稍等一会。
  • 猪猪:好的,那我先打会游戏吧。
  • 老板:饭做好啦,还在打游戏!
  • (老板一个箭步,cua~,直接一整碗塞进猪猪肚子里)
  • 老板:好了,你可以走了。

言归正传,做个总结

数据就绪:根据系统IO操作的就绪状态

  • 阻塞
  • 非阻塞

数据读写:根据应用程序和内核的交互方式

  • 同步
  • 异步

引用一句话:在处理 IO 的时候,阻塞和非阻塞都是同步 IO,只有使用了特殊的 API 才是异步 IO。

一个典型的网络IO接口调用,分为两个阶段,分别是“数据就绪” 和 “数据读写”,数据就绪阶段分为
阻塞和非阻塞,表现得结果就是,阻塞当前线程或是直接返回。

同步表示A向B请求调用一个网络IO接口时(或者调用某个业务逻辑API接口时),数据的读写都是
由请求方A自己来完成的(不管是阻塞还是非阻塞);异步表示A向B请求调用一个网络IO接口时
(或者调用某个业务逻辑API接口时),向B传入请求的事件以及事件发生时通知的方式,A就可以
处理其它逻辑了,当B监听到事件处理完成后,会用事先约定好的通知方式,通知A处理结果。

我会在下一节更新Unix/Linux上的五种I/O模型相关内容,会结合本节内容更深入地进行探讨。

  • 27
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值