Skip to main content

术语与概念

·59 words·1 min
WFUing
Author
WFUing
A graduate who loves coding.
Table of Contents

我们试图建立一个通用的术语来定义一个坚实的基础以对并发、分布式系统这些 Akka 的目标问题展开交流。请注意,对于这些术语并没有一个统一的定义。我们只是为了寻找一些可行的定义以便在整个文档中进行引用。

并发 vs. 并行
#

并发与并行是相关的概念,但有一些不同点。并发意味着有两个或更多任务正在进行,即使不是在同时执行。这种例子可以通过时间切片来实现,其中一部分任务被顺序执行,并与其他部分任务混合。并行在另一方面来说意味着执行会真正的同时发生。

异步 vs. 同步
#

一个方法调用,如果调用者直到方法返回一个值或抛出异常才能继续前进,则被认为这是同步调用。另一方面,一个异步调用允许调用者继续前进有限个步骤,而方法的完成则会通过一些额外的机制来告知调用者(比如注册回调、Future或通过消息)。

无阻塞 vs. 阻塞
#

我们所说的阻塞是指一个线程的延迟会无限期的延迟其他线程。一个很好的例子是一个资源可以通过互斥量被一个线程独占使用。如果一个线程无限期的持有该资源(比如意外进入无线循环),其他线程则无法继续前进。相反,无阻塞则意外着没有线程能够无限期的延迟其他线程。

总是应该更优先选择使用无阻塞操作,因为阻塞操作将导致系统的整体进度无法保证。

死锁 vs. 饥饿 vs. 活锁
#

当多个参与者都在相互等待对方到达一个特殊状态以便程序能够继续进行,则会发生死锁。因为在其他参与者到达一个确定状态(“Catch-22” 问题)之前没有一个能够继续进行下去,从而导致所有受影响的子系统失速。死锁与阻塞紧密相关,因为这必然是由于一个线程无期限的延迟了其他线程的进展。

在死锁的情况下,没有参与者可以继续前进,相反则会发生饥饿,当一些参与者能够继续前进时,仍有一些不能前进。一个经典的场景是源生调度算法总是会选择高优先级的任务而非低优先级的那些。如果进入的高优先级任务的数量总是保持很高,这时没有任何低优先级的任务能够完成。

活锁和死锁类似,也是没有参与者能够继续前进。但与之前被冻结在一个状态等待其他参与者继续前进不同的是,所有的参与者在连续不断的改变他们的状态。比如一个场景,有两个参与者拥有两个完全一致的可用资源。他们互相都在尝试获取资源,但同时也检查对方是否需要该资源。如果一个资源整备其他参与者访问,则该参与者会尝试请求资源的其他实例。不幸的情况是两个参与者可能会在两个资源之间来回跳,从来没有获得,而总是让给对方。

竟态条件
#

如果一组事件的顺序会被外部的不确定因素影响,我们称之为竟态条件。竟态条件经常会发生在多个线程拥有共享的可变状态,而线程对状态的修改操作会被无法预期的行为打乱。虽然通常的情况是这样,但共享状态并非必须要有竟态条件。比如一个例子,一个客户端发送无序的 P1、P2 给服务端。由于包可能通过不同的网络路由传输,服务端可能会先收到 P2 然后才是 P1。如果消息中并不包含服务端可以识别发送顺序的信息,因此基于包的具体含义可能会引起静态条件。

无阻塞保证(Progress Conditions)
#

阻塞由于多种原因是不被提倡的,包括死锁的危险和被缩减的系统吞吐量。

无需等待(Wait-freedom)
#

一个方法的每次调用都保证会在有限个步骤后结束,则称该方法为"wait-free"。如果一个方法是有界的(bounded)“wait-free”,则步骤的数量拥有一个有限的上界(upper bound)。

从这个定义中可以知道无等待方法从不会阻塞,因此死锁也不会发生。另外,因为每个参与者都会在有限个步骤后(即调用结束后)继续前进,无等待方法也不会出现饥饿。

无锁(Lock-freedom)
#

无锁相比无等待是一个较弱的特性。在无锁(lock-free)调用中,有些方法通常无限制的在有限个步骤后结束。这个定义意味着无锁调用永远不会发生死锁。另一方面,一些调用在有限个步骤后结束的保证并不足以保证它们最终都会结束。换句话说就是无锁并不能足以保证饥饿的发生。

无阻碍(Obstruction-freedom)
#

无阻碍是这里讨论的最弱的无阻塞保证。如果一个方法在隔离执行后(其他线程执行任何步骤,比如被挂起)有一个时间点,并在有限数量步骤后结束,则称该方法为无阻碍。所有无锁对象都是无障碍的,但相反则不能成立。

乐观并发控制(Optimistic concurrency control , OCC) 方法通常是无阻碍的。OCC 方式是指每个参与者都尝试在共享对象上执行它们的操作,但是如果一个参与者检测到冲突,它会回滚修改,并根据一些调度规则再次尝试。如果一个时间点只有一个参与者在尝试,操作则会成功。