键盘敲烂,月薪过万作业不做,等于没学
当前系列: 认识计算机 修改讲义

同步和异步

通常情况下,代码/指令是会按固定顺序,依次执行的。前面的代码没有执行完毕,后面的代码就无法执行:这就是同步(sync)执行。

如果代码可以/可能会按书写顺序依次执行,就被称之为异步(async)执行。

PPT演示:

  • 同步:A-B-C-D (放学-写作业-玩手机-打球),始终是这样
  • 异步:A-C-D-B (放学-玩手机-打球-做作业),有可能这次是这样,下次就那样

注意:异步强调的是代码的执行顺序,至于代码被谁执行,不重要。


错误关联

那为什么会出现异步呢?典型的就是因为并行/并发

PPT演示:就像几个人赛跑一样……

于是很多同学会认为:

  • 串行 = 同步
  • 并行 = 异步

其实不对。

还是上面的例子,

  1. 一个厨师一个灶(串行),他:
    1. 可以按既定的顺序,依次炒菜:A->B->C,同步执行
    2. 也可以按照既定顺序,乱炒,这就是异步。你不能说这就是并行哟!
  2. 三个厨师三个灶,一起炒(并行)
    1. 通常情况就是大家随便炒,造成异步
    2. 但也可以(通过锁)按照既定顺序,依次炒菜:A-B-C,这是不是同步

认识到这一点非常重要,不然后面的学习就容易懵。


总结一下(具体到开发):

  • 多线程不一定异步(如下图2所示)
  • 异步也不一定多线程(如下图4所示)


非并发的异步

很多时候异步是(因为并发)被动产生的,但有时候我们却会主动的使用异步。

生活中的例子:顾客在银行窗口排队办理某项业务。

  • 同步的话,必须是前面的业务办理完毕才轮到下一个。
  • 现在,某个顾客A开始办理业务,发现他需要填写一张表格,比较花费时间,于是银行工作人员可以让他在旁边填写,让出位置来接待下一个顾客

接下来当顾客A填完表格后,可能B、C、D……的业务都处理完了。

原来排队的顺序是:A-B-C-D,但现在变成了A-C-D-B,这是不是就是异步?

窗口对应线程,只有一个,所以还是单线程。

计算机运行也可以这样,后面我们要学习的JavaScript的Ajax技术就是典型的单线程异步:所有的Ajax请求扔到最后处理。


异步的烦恼

Ajax单线程的异步简单粗暴,类似于上述银行排队例子:A要填表格,那就让开,填完表格重新排队 —— 这样就不太人性化。

可不可以A填完表格之后就回到队伍中,继续办理业务呢?

可以是可以,但让计算机来处理这事,就比较麻烦了……

我们把排队的顾客想得机械/野蛮一些,A填完表格想C的插队,C眼一瞪:凭啥?!

所以我们大概还需要一个额外的“调度员”来进行管理,大家都听他的,他来维持次序,他的工作就相当相当的复杂,大致会有:

  • 你停下(suspend)
  • 你等着(waiting)
  • 你继续(continue)
  • 你算了(abort)
  • ……

这些都是线程调度的状态(略)

另外,很多时候,下一个步骤的执行,是需要上一个步骤的执行结果的。就比如炒菜之前先要切菜

  • 如果控制得不对,计算机又不是人,还会等一下偷个懒啥的,机器人厨师就可能会“空炒”,带来一堆乱七八糟的问题。
  • 如果控制异步的执行,让厨房一直等着,好像又没必要多线程了?

一堆的问题,非常的麻烦……

你以为的多线程,实际上的多线程(缺图)


阻塞 vs 非阻塞

正如我们前面所说,线程A继续工作(炒菜下锅),需要线程B的结果(切好的菜),但此时线程B还没有完成,线程A只能等待

那么,A在等待的时候:

  1. 是闲着呢?(阻塞,又称之为“挂起
  2. 还是可以继续干其他的活?(非阻塞)

你肯定觉得非阻塞的选项2效率更高。实际上我们主动使用异步的时候,通常使用非阻塞的异步。


DMA

异步要真正的提高性能(让任务被更快的执行完成,归根结底还是要降低CPU的闲置:在等待I/O结果的时候,让CPU做其他事情。

以前要实现这种效果,开发人员写代码就得新开线程。但后来各种语言(我知道的是从C#开始)纷纷推出了异步方法,你直接标记一个方法为异步,这个方法就自然异步执行,语法上非常简洁,更关键的是,文档里特别强调:异步方法不一定会新开一个线程。

what?

查阅了一些文档,其关键在于:

DMA(Direct Memory Access),即直接存储器访问。拥有DMA功能的硬件在和内存进行数据交换的时候可以不消耗CPU资源。

  • 以前,CPU扛下了所有。
  • 现在,DMA分担了数据传输的任务。通过硬件为RAM和IO设备开辟一条直接传输数据的通道,
    1. 只要CPU在发起数据传输时发送一个指令
    2. 硬件就开始自己和内存交换数据,
    3. 在传输完成之后硬件会触发一个中断来通知操作完成。

完美的异步硬件基础!



作业

思考我们现实生活中有哪些并行/并发、同步/异步执行、阻塞/非阻塞的例子:

  1. 说一说他们为什么是为什么不是?
  2. 以及有没有真的解决问题。

注意将他们同CPU、进程/线程、I/O等对应起来。


学习笔记
源栈学历
大多数人,都低估了编程学习的难度,而高估了自己的学习能力和毅力。

作业

觉得很 ,不要忘记分享哟!

任何问题,都可以直接加 QQ群:273534701

在当前系列 认识计算机 中继续学习:

下一课: 已经是最后一课了……

多快好省!前端后端,线上线下,名师精讲

  • 先学习,后付费;
  • 不满意,不要钱。
  • 编程培训班,我就选源栈

更多了解 加:

QQ群:273534701

答疑解惑,远程debug……

B站 源栈-小九 的直播间

写代码要保持微笑 (๑•̀ㅂ•́)و✧

公众号:源栈一起帮

二维码