究竟什么是阻塞与非阻塞、同步与异步

文章目录

前言

这几个名词在程序开发时经常听到,但是突然问起来各个词的含义一时间还真是说不清楚,貌似这几个词都是翻译过来的,每个人的解释都不太一样,我对这几个词的理解也不是一成不变的,随着开发经验的积累,渐渐有了自己的记忆方式,所以总结一下,不一定准确,有问题可以一起聊一聊。

先说说我的结论:阻塞与非阻塞是指等待执行结果时的状态,同步与异步是指获取执行结果的方式,读起来有点绕口,听起来也迷迷糊糊的,没关系,我们用具体的例子来说明应该就容易理解了。

阻塞与非阻塞

先说说『阻塞与非阻塞是指等待执行结果时的状态』这一句,是说在执行某个操作或者某个函数时,在没有拿到我们想要的结果时,我们的状态是怎样的,如果是一直等就是【阻塞】的,如果发现没有结果就去做别的事情了就是【非阻塞】的。

以常见的网络IO为例,服务器对客户端连接的socket调用read函数,试图获取客户端发送的请求数据,但是客户端并不总是有数据发送过来,所以想要获得数据我可以采用【阻塞】方式一直等,也可以采用【非阻塞】方式,在发现此时没有数据时就先去干别的事,一会再来看看。

同步与异步

再来说说『同步与异步是指获取执行结果的方式』这一句,以游戏中的常见升级发奖为例,可以主动调用升级函数,在执行完成后返回升级的结果,然后根据结果来发奖励,也就是【同步】写法,也可以注册一个监听等级变化的回调函数,注册完我就不管了,当升级时会将升级的结果通过回调函数传回来,这就是【异步】处理方式。

复杂的网络IO

为什么同步和异步没有用网络IO来举例呢?因为网络IO这里的情况更加复杂,虽然你注册了回调函数,但它很可能是个同步IO,究竟怎么回事,一起来看看。

我们知道要想从IO读取数据,需要经历「内核数据准备好」和「数据从内核态拷贝到用户态」两个过程,还是以read函数为例,如果设置为阻塞模式,相当于read函数等待了「内核数据准备好」和「数据从内核态拷贝到用户态」两个过程,然后取到IO数据,如果设置成非阻塞模式,当内核数据没准备好会直接返回,也就是不会等待第一个过程,但是当数据准备好时,会直接等待第二个过程完成后,将结果数据返回。

所以无论是否阻塞,我们都等待了第二个阶段,等着它执行完成后获取结果,所以这两种都是同步IO。

那作为IO多路复用里的"一哥"epoll也是同步IO吗?是的!那封装了select/poll/epoll的libevent可是用了Reactor模式,支持事件回调,它也是同步IO吗?是的!

真正的异步IO

有点惊呆了不是吗?那究竟什么是异步IO呢?还真有!Windows 里实现了一套完整的支持 socket 的异步编程接口 IOCP,而 Linux 是在 2019 年 5.1 版本 内核首次引入的高性能异步I/O 框架 io_uring,我确实都没用过,感兴趣的可以试一下

是否是异步IO就看「数据从内核态拷贝到用户态」这个过程需不需要等待,如果需要逻辑层自己等待这个过程取数据就是同步IO,如果这个过程都不用等,调用回调函数时已经把内核态的数据拷贝出来,并且通过回调将数据进行了回传,这就是异步IO。

IO分类与示例

所以总结下来一共有这么几种:同步阻塞IO,同步非阻塞IO,异步IO,为啥不区分异步阻塞IO和异步非阻塞IO呢?你在阻塞时搞个异步试试,办不到吧,所以异步只能与非阻塞搭配,也就习惯只写异步IO了。

一顿理论讲下来可能还是比较抽象,那我们再举个日常生活中的例子,比如中午买饭的过程:

同步阻塞IO就好像,你去食堂吃面条,但是你去这一锅面条还没煮好,然后你就一直在那里等啊等,等了一段时间终于做好了(数据准备的过程),但是你还得继续等工作人员把面条(内核空间)打到你的餐盘里(用户空间),才能找个桌子开始吃饭。

同步非阻塞IO就好像,你又去食堂吃饭,问大叔饭做好了没有,告诉你没有你就离开了,过了一会,你又来饭堂问大叔饭做好了吗,人家说说做好了,于是你等着把饭打到你的餐盘里,后面这个过程你是得等待的。

异步IO就好像,你在十分焦急的写BUG,这时到饭点肚子饿了,给食堂大叔打电话,等饭做好了麻烦给我送一份,等到饭好了真的送来直接就能吃了,一直在抓紧写BUG中间没有等待(做梦中)

我想大部分同学吃午饭都是第一种同步阻塞IO吧,第二种同步非阻塞IO可能也有,但是不是要重新排队啊,如果是第三种异步IO的情况,我只能说大哥/姐,我跟你混了~~

总结

  • IO分为同步阻塞IO,同步非阻塞IO,异步IO三类
  • 异步IO有Windows平台的 IOCP 和 Linux 平台的 io_uring
  • 从IO读取数据,需要经历「内核数据准备好」和「数据从内核态拷贝到用户态」两个过程
  • 分析阻塞和非阻塞看是否等待第一个过程,分析同步与异步看是否等待第二个过程

==>> 反爬链接,请勿点击,原地爆炸,概不负责!<<==


人生的岔路口,不知是机会还是风险,边走边看吧,毕竟路还是在脚下,空想也到不了终点~

相关推荐
风123456789~21 分钟前
【Linux运维】查询指定日期的上月
linux·运维·服务器
CC.cc.1 小时前
Linux系统之systemctl管理服务及编译安装配置文件安装实现systemctl管理服务
linux·运维·服务器
爱写代码的小朋友3 小时前
华三交换机配置常用命令
运维·服务器·网络
wangjun51594 小时前
jenkins 参数化发布到服务器 publish over ssh、label、Parameterized publishing
服务器·ssh·jenkins
愚润求学4 小时前
【Linux】Linux权限
linux·服务器·语法
低头不见4 小时前
一个服务器算分布式吗,分布式需要几个服务器
运维·服务器·分布式
麻芝汤圆4 小时前
使用 MapReduce 进行高效数据清洗:从理论到实践
大数据·linux·服务器·网络·数据库·windows·mapreduce
赋创小助手4 小时前
Gartner预计2025年AI支出达6440亿美元:数据中心与服务器市场的关键驱动与挑战
运维·服务器·人工智能·科技·架构
郑梓妍5 小时前
ubuntu改用户权限
服务器·网络·数据库
H1346948906 小时前
华为服务器系统备份,想要备份华为服务器系统可以怎么操作?
运维·服务器·负载均衡