我有一个关于该设置将发生什么的理论问题。如果我有以下设置,这是死锁还是确切会发生什么?
在fifo队列中,我们按顺序拥有三个进程I,A和B。进程I初始化这些Mutex和变量并终止:
global int i = 1;
global mutex a = false;
global mutex b = true;
然后使用以下代码激活进程A(队列中的下一个):
while(i < 4) {
down(a)
i = i / 2 + 2
up(b)
}
因此,由于互斥体a
无效,循环将开始并且进程A将被锁定。因此,它将从运行队列和睡眠中删除(并插入到a的队列中)。现在,流程B启用了以下代码:
while(i < 4) {
down(b)
i = i + 1
up(a)
}
因此,此时b
未被锁定,因此B进入并且i
现在是2。然后B解锁a
,这在我们的进程队列中要求进程A,但是{由于a
的队列在解锁之前并不为空,因此{1}}仍然被锁定?如果那样的话,案件B接下来将再次击中a
并将自己锁定在执行范围之外吗? down(b)
将在自己的队列中记住B并将B置于睡眠状态。但是现在A可以再次执行,但是在b
仍被锁定的情况下会击中down(a)
吗?因此,两个进程都脱离了进程队列,再也无法运行?
从我们的信息学讲座中我可以理解,但这是真的吗?这些程序将不得不等待外部程序最终解锁权限吗?
答案 0 :(得分:1)
然后B解锁了一个在流程队列中要求流程A的a,但a仍被锁定
您首先说的没错-B
解锁了a
,所以a
处于解锁状态。 A
可以锁定它并继续执行。
结果序列为:
A
试图锁定a
并进入睡眠状态。B
锁定b
,并将i
从1增加到2。B
解锁a
,唤醒A
。B
锁定b
并进入睡眠状态。A
进行i = i / 2 + 1
(i
变为3)并解锁b
,唤醒B
。A
锁定a
并进入睡眠状态。B
从3递增i
到4。B
解锁a
,唤醒A
并退出。A
进行i = i / 2 + 1
(i
仍为4)并解锁b
(由于退出而不会影响B
)并退出。您所说的互斥锁通常称为“信号量”或“二进制信号量”。互斥量一词通常用于二进制信号量的受限版本:始终以未锁定状态创建,只能由锁定它的同一线程来解除锁定。