证明或反驳以下信号量的正确性。
以下是我对此的看法。好吧,如果有人实现了它,所以等待在信号之前先运行,就会出现死锁。程序将调用等待,递减计数,进入计数 < 0 条件并在门等待。因为它在门口等待,所以它不能前往等待之后的信号。所以在这种情况下,这可能意味着信号量不正确。
但是,如果我们假设两个进程正在运行,一个运行等待,另一个运行信号,那么如果第一个进程运行等待并在等待(门)处阻塞,那么另一个进程可以运行信号并释放原来的进程被阻止。因此,继续这个方案将使算法有效并且不会导致死锁。
证明或反驳以下信号量的正确性。
以下是我对此的看法。好吧,如果有人实现了它,所以等待在信号之前先运行,就会出现死锁。程序将调用等待,递减计数,进入计数 < 0 条件并在门等待。因为它在门口等待,所以它不能前往等待之后的信号。所以在这种情况下,这可能意味着信号量不正确。
但是,如果我们假设两个进程正在运行,一个运行等待,另一个运行信号,那么如果第一个进程运行等待并在等待(门)处阻塞,那么另一个进程可以运行信号并释放原来的进程被阻止。因此,继续这个方案将使算法有效并且不会导致死锁。
给定的实现遵循以下原则:
二进制信号量S
保护count
变量免受并发访问。
如果非负数,count
则反映通用信号量的空闲资源数量。count
否则,反映二进制信号量上等待( p5
)或准备等待(在p4
和之间)的线程数的绝对值。p5
gate
每次signal()
调用都会递增count
,如果之前的值为负数,则表示二进制信号量gate
。
但是,由于准备等待状态的可能性,给定的实现是不正确的:
假设thread#1
调用wait()
,并且当前处于准备等待状态。假设另一个thread#2
也调用wait()
,并且当前也处于准备等待状态。
假设此时thread#3
呼叫signal()
。因为 count 是负数 (-2),所以线程执行包括 p10
( signal(gate)
) 在内的所有操作。因为gate
此刻没有等待,它变成了自由状态。
假设此时另一个thread#4
呼叫signal()
。因为count
仍然是负数 (-1),所以线程还执行所有操作,包括p10
. 但现在gate
已经处于自由状态。所以,signal(gate)
这里没有操作,我们错过了信号事件:只有一个thread#1
和thread#2
将在执行后继续p5
(wait(gate)
)。其他线程将永远等待。
如果没有准备好等待状态的可能性(即原子执行) signal(S)
,实现就可以了。wait(gate)