题25

题目

Q:【2021 统考真题】下表给出了整型信号量 S 的 wait() 和 signal() 操作的功能描述,以及采用开 / 关中断指令实现信号量操作互斥的两种方法。

// 功能描述
Semaphore S;
wait(S){
    while(S <= 0);
    S = S-1;
}
signal(S){
    S = S+1;
}
 
// 方法1
Semaphore S;
wait(S){
    关中断;
    while(S <= 0);
    S = S-1;
    开中断;
}
signal(S){
    关中断;
    S = S+1;
    开中断;
}
 
// 方法2
Semaphore S;
wait(S){
    关中断;
    while(S <= 0){
        开中断;
        关中断;
    }
    S = S-1;
    开中断;
}
signal(S){
    关中断;
    S = S+1;
    开中断;
}

请回答下列问题。
(1) 为什么在 wait() 和 signal() 操作中对信号量 S 的访问必须互斥执行?
(2) 分别说明方法 1 和方法 2 是否正确。若不正确,请说明理由。
(3) 用户程序能否使用开 / 关中断指令实现临界区互斥?为什么?

分析

A:因为存在两种操作,wait和signal都要对S进行操作,所以这里要对S进行操作的时候必须是互斥,防止两个操作冲突
我觉得是2不行,因为2的关中断里面不能再有一次关中断,关中断已经是一个原子化的操作了,不能再嵌套关中断,我觉得方法1可以实现这个功能
我觉得用户程序可以通过上面给出的方法实现互斥,实际上方法 1 是错误的。在 wait() 中,当 S0 时,关中断后,其他进程无法修改 S 的值,while 语句陷人死循环。方法 2 是正确的。方法 1 是错误的。在 wait() 中,当 S0 时,关中断后,其他进程无法修改 S 的值,while 语句陷人死循环。方法 2 是正确的。方法 1 是错误的。在 wait() 中,当 S0 时,关中断后,其他进程无法修改 S 的值,while 语句陷人死循环。方法 2 是正确的。方法 1 是错误的。在 wait() 中,当 S0 时,关中断后,其他进程无法修改 S 的值,while 语句陷人死循环。方法 2 是正确的。第三问考察的是内核态下的执行权限的问题

这个第三问原来考的是用户程序能不能使用内核态的关中断指令,在这里角度上看,确实是不可以的
话说为什么不考虑,第二问里面,给while里面又引入了一个关开中断,不就让wait操作存在S被意外篡改的问题吗
因为信号量 S 是能被多个进程进行读写操作的共享变量,所以访问必须互斥。
(1) 因为信号量 S 是能被多个进程进行读写操作的共享变量,所以访问必须互斥。
(2) 方法 1 错误。在 wait 中,如果 S ≤ 0,会导致 while 语句陷入死循环,因为关中断后,当前进程无法被中断,其他进程无法修改信号量 S 的值。
方法 2 正确。方法 2 改进了方法 1 中存在的问题,wait 操作中的 while 循环可以不断重复开中断和关中断的操作,当信号量 S ≤ 0 时,进行 wait 操作的进程无法对 S 进行修改,而此时进行开中断和关中断的循环可以允许其他正在使用 S 信号量的进程执行 signal,从而使得其他进程可以修改信号量 S 的值,从而避免 while 语句的死循环。
(3) 不能。因为用户程序运行在用户态,而开/关中断指令只能在内核态下执行。