<返回更多

计算机与操作系统中无处不在的同步与异步

2022-05-06    醒醒老师
加入收藏

今天读了一本计算机底层的书,书中详细阐述了同步与异步在系统底层方面的处理方法。这篇文章就来讨论一下什么是同步,什么是异步,它们在编程中到底意味着什么。要想写出高性能高并发的代码,这是很关键的基础。

相信很多同学在开始接触到同步异步这两个词的时候大脑一片懵逼,没错,这两个看上去很像实际上也很像的两个词,曾经也让本人深度困扰,以至于夜不能寐。这两个词具体的含义到底是什么呢?

先来看一个咱们身边常见的场景:

美好的一天从打卡开始,现在起你化身为

苦逼程序员

假设现在老板安排给你一个十分紧急的开发任务,让你下班前必须整出来(万恶的资本主义)。为了确保能够完成任务,老板就坐在你旁边看着。

你心里肯定一万头羊驼奔腾而过:“***,这得多闲,干嘛盯着老子,你就不能去干别的?我还怎么摸鱼”

老板仿佛看透你的小心思:“我就在这等着,你写完前我哪儿都不去,别墨迹抓紧整。”

计算机与操作系统中无处不在的同步与异步

 

在上面这个例子中,老板交代给你任务后什么都不做一直等待直到你完成这就是同步的形式。

第二天老板又分配给你新的任务:“小伙子能力真不错,不用多久你就可以升职加薪、当上总经理、出任CEO、迎娶白富美、走上人生巅峰了。不要激动,来,先把今天这个任务完成,不着急,写完告诉我一声就行。”

老板说完就回去刷抖音了,而你经过四五个小时的努力摸鱼后,简简单单就码完了:“老板,我写完了,你来瞅瞅。”

计算机与操作系统中无处不在的同步与异步

 

这个例子中老板安排完以后就干别的事情了,而你写完了告诉老板任务完成,这种就属于异步的概念。

异步相对于同步最明显的不同就是你工作的时候老板在刷剧,这两件事情同时发生,因此从理论上讲异步的效率要高于同步,对大多数场景而言是这样的。

so,so,so!果真遇到在身后盯着写代码的老板,三十六计走为上策!

下面这个场景用来理解同步异步更为鲜明

打电话vs发邮件

作为苦逼程序员不能只会埋头搬砖,工作中总得与客户交流,最常用的方式就是打电报。。。啊不,是打电话。

通常我们打电话都是一个人说另一个人听,对方讲话的时候我方需要等待,等对方讲完再接着说,而且每一步都依赖之前的讲话。这里的重点是产生了等待,不可避免地等待,这种方式就是同步的特点。

计算机与操作系统中无处不在的同步与异步

 

作为搬砖码农,另外一种比较常用的方式就是发邮件,尤其是在公司内部。没有人为了等你的邮件什么都不做,他可以摸摸鱼,充下电,上个厕所等等。同样的你发完邮件也不需要一直等着对方的回复,这期间可以做其他有意义的事情。

计算机与操作系统中无处不在的同步与异步

 

在这种方式中,写邮件和收件人摸鱼这两件事情同时发生着,双方都不需要等待,两件事情也不存在依赖,这就是异步的方式。

编程中的同步

现在回到编程的主题,上面场景展示了生活中的同步异步的意义,那么在程序开发中又该怎样理解呢?

一般情况下函数的调用都是这样的

/**JAVAscript */
function A( ){
    //等待函数b完成
    function B( )
    //继续后面的运行
}

函数A调用函数B,那么在B完成前A都不会执行后续的代码,就像这样:

计算机与操作系统中无处不在的同步与异步

 

从上图看到B执行期间A什么都不能做,这就是同步。

下面这段Node代码就是采用同步的方式执行磁盘文件读取,属于阻塞式I/O

/**JavaScript */
import { readFileSync } from 'fs';

readFileSync('<directory>');//程序暂停运行,等待I/O返回数据
//文件读取完成后继续运行

同步编程对程序员是最好理解的,一步完成再做下一步,但代价就是在某些场景(例如I/O操作)下这种方式的效率不够高效,因为任务没法同时进行。

编程中的异步

有同步就有异步,在理解了前面的内容后相信很快就能掌握异步的要领。

一般来说在程序开发中,一些耗时比较高的任务都是采用异步的方式,例如磁盘读写,网络数据收发,数据库命令的执行等。同样以磁盘文件读取为例,使用异步函数即使文件还没有读取完毕后面的代码也能执行。

/**javascript */
import { readFile } from 'fs';

readFile('<directory>', callback);//readFile函数立即返回
//不会阻塞程序的执行
//某个时间点文件读取完成后执行callback回调

异步的重点在于调用函数后接下来的程序可以继续和文件读取同时执行,这就是高效之处。

然而,异步执行对程序员来说是一种负担,无论在阅读还是编写上都不容易理解。

有的同学可能会问,同步的情况下可以得到函数的结果继续执行,那么异步的时候又怎么知道函数执行完成了呢?

这里一分为二:

  1. 不需要关心结果,执行就ok
  2. 需要结果进行更多的操作

第一种无需讨论,比较简单。

第二种情况通常有两种方式,一种是通知机制,任务完成后发送信号通知上一级,例如linux的signal方式。还有一种就是回调,就是我们常说的callback。

最后需要注意的是,并非所有的情况下异步就一定比同步高效,还要结合具体的业务或者I/O复杂程度来分析。但是不管何时何地,同步意味着双方要相互等待,相互依赖,二异步则意味着双方相互独立,各行其道。希望这篇文章对大家理解这两个重要的概念有所帮助。

声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多资讯 >>>