操作系统中信号量简介

2025年3月17日 | 阅读 12 分钟

在本教程中,我们将学习一个非常重要的主题——信号量。可以 100% 确定,在口试、面试、考试甚至实习选拔考试中,都会出现关于信号量的主题。因此,请务必仔细并优先理解此主题。

在本主题中,我们将学习信号量的定义、信号量的类型、信号量的操作、信号量的优缺点,以及使用信号量解决经典同步问题的过程,以及这些信号量类型在解决这些经典同步问题中的应用。

信号量定义

信号量是一种硬件解决方案。这种硬件解决方案是为临界区问题而编写或提供的。

什么是临界区问题?

临界区问题是指一段代码片段。这段代码片段包含一些变量。这些变量可以被几个进程访问。这些进程有一个条件。

条件是只有一个进程可以进入临界区。其他有兴趣进入临界区的进程必须等待该进程完成其工作,然后才能进入临界区。

临界区表示

Introduction to Semaphore in Operating Systems (OS)

临界区问题中的问题

可能出现一种情况,一个或多个进程尝试进入临界状态。在多个进程进入临界区后,第二个进程尝试访问第一个进程已访问的变量。

说明

假设有一个变量,也称为共享变量。让我们定义这个共享变量。

这里,x 是共享变量。

方法 1

方法 2

如果进程一个接一个地访问 x 共享变量,那么我们将处于一个有利的位置。

如果 Process 1 单独执行,则 x 的值表示为 x = 30;

共享变量 x 从 10 变为 30

如果 Process 2 单独执行,则 x 的值表示为 x = -10;

共享变量 x 从 30 变为 -10

如果两个进程同时发生,那么编译器将陷入混乱,不知道选择哪个变量值,即 -10 或 30。变量 x 面临的这种状态是数据不一致。这些问题也可以通过硬件锁来解决。

为了防止此类问题,也可以通过名为信号量的硬件解决方案来解决。

信号量

信号量就是一个普通的整数。信号量不能为负数。信号量的最小值是零 (0)。信号量的最大值可以是任何值。信号量通常有两个操作。这两个操作能够决定信号量的值。

两个信号量操作是

  1. Wait ( )
  2. Signal ( )

Wait 信号量操作

Wait 操作用于决定进程进入临界状态或等待进程执行的条件。这里,wait 操作有许多不同的名称。不同的名称是

  1. Sleep 操作
  2. Down 操作
  3. Decrease 操作
  4. P 函数(wait 操作最重要的别名)

Wait 操作基于信号量或互斥锁的值进行工作。

在这里,如果信号量值大于零或为正,则进程可以进入临界区。

如果信号量值为零,则进程必须等待进程退出临界区。

此函数仅在进程进入临界状态时存在。如果进程进入临界状态,那么 P 函数或 Wait 操作就无事可做。

如果进程退出临界区,我们必须减少信号量的值。

P 函数或 Wait 操作的基本算法

Signal 信号量操作

Signal 信号量操作用于更新信号量的值。当新进程准备进入临界区时,信号量值会更新。

Signal 操作也称为

  1. Wake up 操作
  2. Up 操作
  3. Increase 操作
  4. V 函数(signal 操作最重要的别名)

我们知道,在 Wait 操作中,当进程离开临界状态时,信号量值会减一。因此,为了抵消减少的 1,我们使用 Signal 操作来增加信号量值。这会促使临界区接收越来越多的进程。

最重要的是,此 Signal 操作或 V 函数仅在进程退出临界区时执行。在进程退出临界区之前,信号量的值不能增加。

V 函数或 Signal 操作的基本算法

信号量类型

信号量有两种类型。

它们是

1. 二元信号量

在这里,二元信号量概念中有两个信号量值。这两个值是 1 和 0。

如果二元信号量的值为 1,则进程有能力进入临界区。如果二元信号量的值为 0,则进程没有能力进入临界区。

2. 计数信号量

在这里,计数信号量概念中有两组信号量值。两种值是大于等于一的值,另一种是等于零的值。

如果二元信号量的值大于等于 1,则进程有能力进入临界区。如果二元信号量的值为 0,则进程没有能力进入临界区。

这是关于二元信号量和计数信号量的简要描述。您将在接下来的文章中了解更多关于它们的信息。

信号量的优点

  • 信号量是机器无关的,因为它们的实现和代码都写在微内核的机器无关代码区域。
  • 它们严格执行互斥,并允许进程一次进入关键部分(仅在二元信号量的情况下)。
  • 使用信号量,由于我们不需要处理器时间来验证一个条件是否满足即可允许进程访问关键区域,因此不会因忙等待而丢失任何资源。
  • 信号量具有非常好的资源管理能力。
  • 它们阻止多个进程进入关键区域。它们比其他同步方法有效得多,因为通过这种方式可以实现互斥。

信号量的缺点

  • 由于使用了信号量,高优先级进程可能会在低优先级进程之前进入关键区域。
  • 因为信号量有点复杂,所以必须以避免死锁的方式设计 wait 和 signal 操作。
  • 编程信号量非常具有挑战性,并且存在无法实现互斥的风险。
  • 必须以正确的顺序执行 wait ( ) 和 signal ( ) 操作以避免死锁。

现在,让我们使用信号量的概念来解决经典的同步问题。

使用信号量概念解决经典的同步问题

1) 使用信号量解决读者-写者问题

定义

首先,让我们都了解一下读者-写者问题。

在读者-写者问题中,存在两个角色:读者和写者。读者-写者问题试图访问或更改共享变量的值。由于这种并行访问和更改操作,会导致数据错误。因此,预期的输出不是问题的实际输出。这就是读者-写者问题。

读者和写者的职责是不同的。

读者负责读取共享变量的值。

写者负责更改共享变量的值。

现在,让我们通过信号量来解决这个问题。

所需数据

首先,让我们考虑存在一个包含共享变量的临界区。让我们考虑有两个进程。第一个进程总是尝试访问共享变量。第二个进程总是尝试更改变量的值。

解决方案

现在,让我们用以下方法理解读者和写者问题的解决方案:

现在,我们的任务是使用信号量执行读者和写者的操作,而不会出现任何死锁的可能性。

使用二元信号量解决读者-写者问题

我们知道,如果二元信号量的值为 1,它允许进程进入临界区。

现在,我们将允许写者工作或执行其任务,如果二元信号量的值为 1。这允许数据更改是无错误的。

我们可以允许读者工作或执行其任务,如果二元信号量的值为 1 或 0。这是因为读者只是读取共享变量的值。但根据信号量制定的规则。我们只能在信号量值大于等于 1 时才能进入临界区。

因此,如果信号量值为 1,我们可以允许读者。

使用二元信号量解决读者-写者问题的算法

使用计数信号量解决读者-写者问题

我们知道,如果计数信号量的值大于等于 1,它允许进程进入临界区。

现在,我们将允许写者工作或执行其任务,如果计数信号量的值大于等于 1。这允许数据更改是无错误的。

我们可以允许读者工作或执行其任务,如果计数信号量的值大于等于 1 或计数信号量等于 0。这是因为读者只是读取共享变量的值。但根据信号量制定的规则。我们只能在计数信号量值大于等于 1 时才能进入临界区。

因此,如果计数信号量的值大于等于 1,我们可以允许读者。

使用二元信号量解决读者-写者问题的算法

2. 使用信号量概念解决有界缓冲区问题

定义

生产者-消费者问题是有限缓冲区的另一个名称。在这个问题中,缓冲区中有 n 个槽,每个槽可以容纳一个数据单元。生产者和消费者是使用缓冲区的两个操作。生产者和消费者都尝试进入和删除数据。

解决方案

现在,我们将解决有界缓冲区或生产者消费者问题中遇到的问题。

我们已经知道生产者的任务是在任何可能的地方输入数据。

消费者的任务是删除生产者产生的数据或已存在的数据, wherever possible。

现在,让我们了解这两个生产者和消费者如何与二元信号量和计数信号量的概念一起工作。

使用二元信号量解决有界缓冲区或生产者消费者问题

我们知道,如果二元信号量的值为 1,它允许进程进入临界区。

现在,我们将允许写者工作或执行其任务,如果二元信号量的值为 1。这允许数据更改是无错误的。

现在,让我们假设生产者在临界区内创建了一些共享变量。

现在,让我们允许名为 Producer 的进程在进入临界区后在临界区内生成新值。只有当二元信号量的值等于 1 时,才接受进入。

现在,让我们允许名为 Consumer 的进程在进入临界区后删除已创建的进程。只有当二元信号量的值等于 1 时,才接受进入。

现在,我们的职责是防止生产者和消费者同时执行。因此,我们在进入临界区入口段时,为用户或计算机提供一个选项来选择要执行的操作。

使用计数信号量解决有界缓冲区或生产者消费者问题

我们知道,如果计数信号量的值为 1 或大于 1,它允许进程进入临界区。

现在,我们将允许写者工作或执行其任务,如果计数信号量的值为 1 或大于 1。这允许数据更改是无错误的。

现在,让我们假设生产者在临界区内创建了一些共享变量。

现在,让我们允许名为 Producer 的进程在进入临界区后在临界区内生成新值。只有当计数信号量的值等于或大于 1 时,才接受进入。

现在,让我们允许名为 Consumer 的进程在进入临界区后删除已创建的进程。只有当计数信号量的值为 1 或大于 1 时,才接受进入。

现在,我们的职责是防止生产者和消费者同时执行。因此,我们在进入临界区入口段时,为用户或计算机提供一个选项来选择要执行的操作。

3. 使用信号量概念解决哲学家就餐问题

定义

Dining philosopher's dilemma,也称为经典同步问题,有五个哲学家围坐在圆桌旁,他们必须在思考和吃饭之间交替。桌子中央放着一碗面条和五双筷子,每位哲学家一双。哲学家吃饭时必须同时使用左右筷子。只有当哲学家左右筷子都在身边时,哲学家才能吃饭。如果哲学家左右筷子不可用,哲学家就会放下其中一双筷子(左或右)继续思考。

Dining Philosopher 是一个经典的同步问题,因为它说明了一类广泛的并发控制问题。

现在,您可能已经理解了信号量在解决同步过程产生的问题方面的作用。

以上是操作系统中信号量的全部内容。


下一个主题计数信号量