2024 操作系统 进程概念信号量 解答题
第 46 题

计算机系统中的进程之间往往需要相互协作以完成一个任务,在某网络系统中缓冲区 B 用于存放一个数据分组,对 B 的操作有 C1、C2 和 C3。C1 将一个数据分组写入 B 中,C2 从 B 中读出一个数据分组,C3 对 B 中的数据分组进行修改。要求 B 为空时才能执行 C1,B 非空时才能执行 C2 和 C3。请回答下列问题。

(1)假设进程 P1 和 P2 均需执行 C1,实现 C1 的代码是否为临界区?为什么?(2 分)

(2)假设 B 初始为空,进程 P1 执行 C1 一次,进程 P2 执行 C2 一次。请定义尽可能少的信号量。并用 wait(),signal() 操作描述进程 P1、P2 之间的同步或互斥关系,说明所用信号量的作用及初值。(3 分)

(3)假设 B 初始不为空,进程 P1 和 P2 各执行 C3 一次,请定义尽可能少的信号量。并用 wait()、signal() 操作描述进程 P1 和 P2 之间的同步或互斥关系,说明所用信号量的作用及初值。(3 分)

进程概念 信号量

[tag_link]

1)是的,实现 C1 的代码可以被视为临界区。临界区是指在并发编程中,当多个进程同时访问和修改共享数据时,必须进行互斥访问的代码区域。在这个例子中,进程 P1 和 P2 都需要执行 C1,即它们都需要将一个数据分组写入缓冲区 B。如果这两个进程同时执行 C1,那么它们可能会试图同时写入数据分组,这可能会导致数据的不一致性。因此,我们需要确保在任何时刻,只有一个进程可以执行 C1。这就需要将执行 C1 的代码区域定义为临界区,并使用适当的同步机制(如互斥锁或信号量)来保证在同一时刻只有个进程可以进入临界区。所以,实现 C1 的代码是临界区,因为它涉及到对共享资源(在这里是缓冲区 B) 的修改,而这个修改需要被同步,以防止数据的不一致性。

2)在这个问题中,我们可以使用两个信号量:一个用于保护缓使区 B(我们称之为 mutex),另一个用于同步进程 PI 和 P2(我们称之为 full)。mutex 用于确保在同一时刻只有一个进程可以访问缓冲区 B,而 full 用于表示缓冲区 B 是否已满。初始时,mutex 的值为 1,表示缓冲区 B 是可用的:fu1I 的值为 0,表示缓冲区 B 是空的。以下是进程 P1 和 P2 的代码:

semaphore mutex = 1;
semaphore full = 0;

// 进程 P1
P1() {
    wait(mutex);    // 请求访问缓冲区 B
    执行 C1,将一个数据分组写入 B 
    signal(mutex);  // 释放缓冲区 B 的使用权
    signal(full);   // 表示缓冲区 B 已满
}

// 进程 P2
P2() {
    wait(full);     // 等待缓冲区 B 变满
    wait(mutex);    // 请求访问缓冲区 B
    执行 C1,从 B 中读出一个数组分组
    signal(mutex);  // 释放缓冲区 B 的使用权
}

在这个代码中,wait() 操作表示请求一个信号量,如果信号量的值大于 0,那么就将其减 1:如果信号量的值为 0,那么就阻塞,直到信号量的值大于 0。signal() 操作表示释放一个信号量,将其值加 1。

3)在这个问题中,我们可以使用一个信号量:一个用于保护缓冲区 B(我们称之为 mutex)。mutex 用于确保在同一时刻只有一个进程可以访问缓冲区 B。初始时,mutex 的值为 1,表示缓冲区 B 是可用的。以下是进程 P1 和 P2 的代码:

semaphore mutex=1;

// 进程 P1
P1() {
    wait(mutex);     // 请求访问缓冲区 B
    执行 C3, B 中的数据分组进行修改
    signal(mutex);   // 释放对缓冲区 B 的访问
}
// 进程 P2
P2() {
    wait(mutex);     // 请求访问缓冲区 B
    执行 C3, B 中的数据分组进行修
    signal(mutex);   // 释放对缓冲区 B 的访问
}

在这个代码中,wait() 操作表示请求一个信号量,如果信号量的值大于 0,那么就将其减 1;如果信号量的值为 0,那么就阻塞,直到信号量的值大于 0。signal() 操作表示释放一个信号量,将其值加 1。所以,实现 C3 的代码是临界区,因为它涉及到共享资源(在这里是缓冲区 B)的修改,而这个修改需要被同步,以防止数据的不一致性。