标签归档:并行

“并行,并发,异步,同步,阻塞,非阻塞”之我见

后台开发中总是在”并行,并发,异步,同步,阻塞,非阻塞”之间转,自己经常就被转得晕头转向。由于对基于经验的答复不满意,因此决定将我这几个月对这些概念千丝万缕的思绪整理出来。

【并发与并行】

  • 并发: 仅仅包含宏观上的意义,即多个任务同时被处理;而微观上可能仅仅是一个cpu分时间片去完成了多个任务,这个时候多个任务是被顺序处理的。
  • 并行: 则更加严格,在宏观和微观上都应该具有多个任务同时被处理的含义,这个意义上多个任务被并行处理的,单cpu永远不可能并行。
=>
  1. 并行和并发是站在两个不同角度上理解产生的概念。
  2. 并行一定是并发,并发却不一定是并行。

【同步与异步】

  • 同步: 任务的执行过程是顺序的。
  • 异步: 事情的执行过程不是线性的。
=>
  1. 异步和同步是从任务被执行的顺序上来区分的,从这个基本概念出发,异步并不见得比同步性能高,也就是说异步模型不见得会比同步模型有优势。
  2. 然而异步和同步这个概念却非常容易和阻塞与非阻塞混淆,因为任何一个任务理论上都不可能瞬间完成,而现实中的任务通常都需要与其他系统交互,因此可能被阻塞是不可避免的。
  3. 异步通常给人一个错觉,就是他比同步快。这里其实是有一个误区,因为一个任务实际被处理的时间并没有太大变化,只有在带阻塞的任务中,异步才可能 比同步快,因为异步快在将同步模式下带阻塞任务执行过程中cpu的等待时间利用起来处理其他任务,借此提升了多任务系统的整体并发能力,可见,一个任务的 异步不一定比同步快,同时,对于处理不阻塞的任务,异步模型也不会比同步模型快。

【阻塞与非阻塞】

  • 阻塞: 任务的执行会使cpu进入等待状态。
  • 非阻塞: 任务的执行不会主动让cpu进行等待。
=>
  1. 阻塞不阻塞的原始语义实际上是看任务在宏观执行过程中对cpu的主动占用情况是否连续来区分的。
  2. 在不考虑cpu时间片耗尽被重新调度或者其他干扰导致被抢占的情况下,非阻塞的任务在获得cpu后将一直执行到完成。
  3. 阻塞或非阻塞的任务与阻塞或非阻塞的接口是有区别的:前者隐含一个前提就是必须是任务执行从开始到结束的整个过程,而后者不用关心任务是否完整完成,仅仅关心当前这一步操作是否会阻塞。

【开发中的现状】

  1. 大部分业务都可能阻塞(网络IO,文件IO),常见的网络收发,数据库操作等,因此在追求海量高性能的server开发中很较少用到同步模型,这也是为什么我们潜意识里会觉得同步模型慢且容易与阻塞纠缠不清的原因 — 计算机世界的任务模型原本大多是阻塞任务。
  2. 开发中大多是将带阻塞的任务分解成多个不阻塞的部分(这就是异步模型中所谓的分割点),只有在这样的前提下配合异步模型才能大幅提升系统的并发能力,这就是为什么在高性能server开发中异步与非阻塞通常被混为一谈的原因 — 计算机处理海量任务只有这样才能整体最快。
  3. 对server业务,肯定提倡使用异步模型。但异步模型对开发者并不友好,因为人类的思维习惯是线性分析事务,这就是为什么大部分开发者愿意使用同步模型的原因 — 人类看待事物的习惯本就带有顺序性。