Operating system 带测试集的有界等待互斥

Operating system 带测试集的有界等待互斥,operating-system,synchronization,locking,mutual-exclusion,Operating System,Synchronization,Locking,Mutual Exclusion,我正在阅读著名的操作系统概念书(Avi Silberschatz,Peter Baer Galvin,Greg Gagne)第9版: 在“进程同步”一章中,有一个“测试_和_集的有界等待互斥”算法,如下所示: do { waiting[i] = true; key = true; // <-- Boolean variable that I do not see its utility while (waiting[i] && key) // &l

我正在阅读著名的操作系统概念书(Avi Silberschatz,Peter Baer Galvin,Greg Gagne)第9版:

在“进程同步”一章中,有一个“测试_和_集的有界等待互斥”算法,如下所示:

do {
    waiting[i] = true;
    key = true;  // <-- Boolean variable that I do not see its utility
    while (waiting[i] && key) // <-- the value of the key variable here is always true
        key = test_and_set(&lock); // <-- it might become false here, but what is the point?
    waiting[i] = false;

    /* critical section */

    j = (i + 1) % n;
    while ((j != i) && !waiting[j]) 
        j = (j + 1) % n; 
    if (j == i) 
        lock = false; 
    else
        waiting[j] = false;

    /* remainder section */
} while (true); 
do{
等待[我]=真;

key=true;//您可以将算法简化为:

do {
    waiting[i] = true;
    while (waiting[i] && test_and_set(&lock)) ;
    waiting[i] = false;

    /* critical section */

    j = (i + 1) % n;
    while ((j != i) && !waiting[j]) 
        j = (j + 1) % n; 
    if (j == i) 
        lock = false; 
    else
        waiting[j] = false;

    /* remainder section */
} while (true);
我猜作者使用了
key
,因为他们认为这样会使代码更容易阅读

如评论中所问:

通常,在使用
test\u和\u set
时,只需执行
while(test\u和\u set(&lock))
。但是,在这种情况下,您希望确保线程只等待有限的锁定时间。这是通过
waiting
数组完成的。在关键部分的末尾,当我们解锁时,我们不只是简单地将
lock
设置为false,这是您通常解锁它的方式。相反,我们尝试找到下一个t等待锁定的线程。下一步,我的意思是增加线程ID,然后在点击
n
j=(j+1)%n;
部分)时循环。如果找到这样一个线程
j
,我们将
等待[j]
设置为
false
,而不是
锁定

这可以防止两个或多个线程不断获取锁,而另一个线程或一组线程总是在等待。例如,假设3个线程正在等待同一个锁(线程0、1和2)。假设线程0释放锁,然后线程1抓住它。当线程1拥有锁时,线程0尝试再次抓住锁,当线程1释放锁时,线程0抓住锁,而不是线程2。这可能会无限期重复,线程2永远不会得到锁


在这个使用
waiting
数组的边界等待算法中,这种行为不会发生。如果三个线程不断地抓取锁,那么根据线程ID,下一个线程将进入下一个线程,例如线程0将抓取并释放锁,然后是线程1,然后是线程2。这是因为每个线程都在等待ei
lock
或它在
waiting
数组中的条目变为
false
。如果另一个线程正在等待锁,当一个线程即将释放锁时,它会设置
waiting
条目,而不是
lock
仅将该线程从旋转等待中释放。这可以防止出现一个或多个线程的病态情况或者线程无限期地等待锁。

我们甚至可以这样做:while(test_和_set(&lock));对吗?这就是您通常使用它的方式,但这违反了此算法的有界等待属性。@Rami我已更新了我的答案,如果有任何混淆,请让我知道在这种清晰程度上解释是一种绝对的天赋@esm!非常感谢,现在已经非常清楚了!我怀疑如果j==I,我的意思是如果j==它意味着同样的进程也要在CS中,那么“if(j==i)lock=false;”有什么用呢?我想它会再次允许该进程(j)进入CS将违反有界等待。不是吗?密钥是这里用于退出while循环的两种方法之一,如果lock为false,则将其设置为false,从而使当前进程能够执行其关键部分。