操作系统中的活锁

2025 年 4 月 23 日 | 2 分钟阅读

在本文中,您将学习操作系统中的活锁。

什么是活锁?

当由于多个重叠的共享锁不断干扰而导致独占锁的请求被持续拒绝时,就会发生活锁。进程状态不断变化,阻止它们完成任务,并使完成任务更加困难。

当多个进程对其他进程的变化做出反应,反复执行相同的交互而未执行任何有用工作时,就会发生这种情况。这些进程不处于等待状态,并且同时运行,这与死锁不同,因为死锁中的所有进程都处于等待状态。

活锁的例子

活锁的各种例子如下:

示例 1

活锁的一个常见例子是,当两个人走廊里面对面相遇时,两人都向旁边让路以便对方通过。由于他们同时朝同一个方向移动,结果他们左右摇摆,没有取得任何进展。因此,他们未能相互通过。

示例 2

活锁的另一个例子是,当两个进程需要两个资源时,它们使用原始的轮询进入注册表来获取所需的锁。如果第一次尝试失败,将进行第二次尝试。假设:

Livelock in Operating System
  1. 进程 A 持有 Y 资源
  2. 进程 B 持有 X 资源
  3. 进程 A 需要 X 资源
  4. 进程 B 需要 Y 资源

假设进程 A 先运行并获取了数据资源 X,进程 B 后运行并获取了资源 Y,无论哪个进程先运行,都没有进程能够取得进展。尽管如此,没有一个进程被阻塞。它们持续使用 CPU 资源而没有取得任何进展,但它们也会阻止任何处理阻塞。因此,这不是死锁,因为没有单个进程被停顿,但你处于一种类似于死锁的状态,那就是活锁。

是什么导致了活锁?

当一个给定系统中允许的总进程数必须由进程表中的条目数来定义时,就会发生活锁。因此,进程表槽应该被称为有限资源。如果由于表已满而导致 fork 失败,fork 程序应该等待随机时间,然后再重试。

以一个拥有 100 个进程槽的 UNIX 系统为例。10 个程序正在运行,每个程序负责创建 12 个(子)进程。在每个进程创建了 9 个新进程之后,该表已被 10 个原始进程和 90 个新进程耗尽。10 个原始进程中的每一个都陷入了永无止境的 fork 和失败循环,这被称为死锁。尽管这种情况发生的几率很小,但也有可能发生。