同步与异步

发布 : 2019-01-06 分类 : basics 浏览 : --

同步与异步的概念其实并不局限于计算机或者程序中线程或进程之间的同异步,同步与异步这种关系性可以扩展到任意两个过程之间

过程性

首先,同步与异步 涉及的对象是多个 过程

过程的范围可能超乎想象,从一个进程的执行过程到一个线程的执行过程可以认为是一个过程,他们可以被认为是程序中最常用的过程。但如果思路开阔,其实 任何占用时间 或者说 需要消耗时间来完成 的事都可以是这里的过程

在程序中,一个函数的执行是一个过程,一个循环的展开也是一个过程,甚至一个变量的赋值也是一个过程,因为其中涉及到对寄存器的一系列操作。在车道上,车辆运行是一个过程,转动方向盘是一个过程,刹车也是一个过程。事无巨细的每一点一滴都需要消耗时间来完成,可以说过程本身就是时间,不一样的是每个过程的生命周期可能都是不一样的,有的过程先发生,有的过程先结束。就像不同人的人生一样,每个人都有自己的生命周期,自己的过程

真理往往简短,推动万物向前的过程也应该单纯

同步与异步的判定与过程的完整性并没有关系,或者说无论多细致的过程都可以是独立的过程或者被干扰的非独立过程。然而就理论而言,貌似并没有人能找到那个绝对独立的过程,或者说被干扰最少的过程,这个过程也许就是人们追寻的万物的本源,一切的驱动力。然而人类无法依靠测试的手段来找寻这个过程的存在,因为没人没见过薛定谔的猫

如果存在一个独立的过程,那它一定是自我同步的,原子的;如果存在多个独立的过程,那么这些过程之间就是异步的关系。如果两个过程之间产生了干扰,即为 同步过程 ,使得两个过程产生了联系。多数情况下,这种联系都不是单一驱动因素(甚至是间接的因素)造成的,不过对于关注的过程而言,可以假定这个同步过程是明确的。

确定过程

在关系性(或者说 因果 )明确的情况下,两个原子过程如果是同步的,一定是一个过程的 结束 带来了另一个过程的 开始

1
2
a = 1 # 过程1: 给 a 赋值 1
a += 1 # 过程2: 让 a 自增 1

上述两个过程,如果解释器正确执行(即因果明确)的情况下,赋值过程的结束将带来自增过程的开始。在得到 a = 2 的整个过程中包含了一次明显的同步过程,有明确的 先后顺序,是一段确定过程。从中可以得到两点:

  1. 多个过程的同步可以看作是一个完整过程,一个完整过程可以拆分为多个同步过程
  2. 多个原子过程如果是同步的,则这是一个确定过程

还有隐含的一点就是:后开始的过程需要等待上一个过程结束,如果这些过程发生在同一时间轴上,则时间就会被消耗在 等待 上。

随机过程

多个异步过程放在一起,可以当作一系列的随机过程。如果他们具有一定的统计学分布,那背后一定存在某种同步。

随机过程无法掌握,就像多个异步过程无法确定哪一个先开始,哪一个先结束。

真正的异步的确无法得知其确切的开始与结束。如果知道,那在知道这些过程开始之前一定进行了更大范围甚至更高维度的外部同步。异步,代表了不确定性,就像薛定谔的猫一样,有辣么多猫,谁都不知道过程到了哪一步,直到以某种方式进行干预(测试),打破随机过程,将异步过程与观察者同步

虽然说了辣么多,但同步与异步讨论的其实过程之间的 关系性 ,以上,只是为了将过程的概念从程序中的进程、线程等过程进行拓展,以免思维被束缚

抛开关系性说同步、异步都是在耍流氓

关系性

有了过程,过程之间就会有这样那样的关系,直接或者间接的关系。同步与异步 说的一直都是 过程 之间的 关系

  1. 如果存在因果关系,则过程之间为 同步关系
  2. 如果没有任何关系,则过程之间为 异步关系

给定一个过程:

  1. 如果它是所有因果的起点,那么可以说它是 自同步 的,因为它是万物的起因,也可以说它是异步的,因为它跟其他过程毫无关系,是自驱的过程 (万物的起点与万物的关系)
  2. 否则它既不能说同步,也不能说异步,因为 同异步 指的是过程之间的关系性,无法独立存在

所以,一个过程,除非它解释了万物存在的理由,那么就无法用同步与异步进行描述,无论如何都需要一个参照

这种关系性存在以下特点:

  1. 相对性
  2. 复杂性

相对性

两个过程之间是同步关系还是异步关系,与观察尺度有关。往往在小尺度上的异步,在大尺度下其实是同步的

1
2
3
4
5
def p1(args):
pass

def p2(args):
pass

如果仅看上述例子,谁也不知道 p1p2 谁先被调用,甚至都不被调用,但是如果加上下面的代码

1
x = p1(p2())

那么两个过程的执行先后就确定了下来

对于更加复杂的调用环境,要理出两个过程之间的同步关系则要更难一些,甚至不可能

1
2
3
4
if random() > 0.5:
p1(p2())
else:
p2(p1())

这个时候,两个的执行顺序变成了随机的,虽然这个顺序具有统计学概率上的确定,但是在过程结束之前,谁都不知道究竟会发生什么

也就是说,如果将参考换为彼此两个过程,除非两者存在直接的联系,否则都可以看作是异步过程;如果将参考换为两者共同的背景,则可以看作是一个同步过程,有环境作为两者共同的因果

复杂性

复杂性来源与过程本身的复杂性以及因果的复杂性

  1. 过程本身可以拆分为更小的过程,更小的过程之间拥有着各种同步关系,小范围的同步才能形成最终的过程
  2. 因果不一定简单的直接关系,多见为间接关系(比如亚马逊的蝴蝶煽动翅膀这个过程导致宇宙坍塌等等),因果并不直观

同步过程

因为有着各种各样的过程需要我们组合为自己需要的过程,所以需要 同步过程 来联系各个简单过程。

建立两个过程之间的同步关系,本质上是让两者建立因果

建立因果的方式有两种:

  1. 直接因果 (彼之果即为此之因)
  2. 间接因果 (媒妁之言)

直接因果的关系往往直观明了

1
2
3
4
5
6
7
def p1(args):
pass

def p2(args):
pass

p1(p2())

p2 的果即为 p1 的因

间接因果则需要媒介

1
2
3
4
5
6
7
8
9
10
x = []

def p1(a):
pass

def p2(b):
pass

p1(x)
p2(x)

多进程或多线程中的同步也是通过间接因果的方式进行

函数式编程中则大多数采用直接因果,并且尽量避免一个执行过程带来多种影响,甚至是影响环境上下文。也就是单因果的简单形式,可以使得整个过程的目的尽量单一,专注于目标因果

命令式编程则比较容易在过程中导致意想不到的因果,干扰了产生的结果,给人一种异步的错觉,难以捉摸


总而言之

异步本身并不复杂,复杂的是如何将将异步的过程同步起来

本文作者 : hellflame
原文链接 : https://hellflame.github.io/2019/01/06/sync-and-async/
版权声明 : 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
留下足迹
点击通过issue留言