如果我跳过等待[i] = false会发生什么在下面的代码片段中?

时间:2015-01-05 19:06:42

标签: c operating-system synchronization deadlock

以下代码旨在解决关键部分问题。鉴于有N个进程正在修改其关键部分中的公共数据结构。

这些是使用的数据结构:

boolean waiting[n];
boolean lock;

这是testAndSet()函数,假定由于硬件支持而原子执行。

boolean TestAndSet(boolean *target) 
{
    boolean rv = *target;
   *target = TRUE;
    return rv;
}

//以下代码可确保互斥

do {
    waiting[i] = TRUE;
    key = TRUE;

    while (waiting[i] && key)
        key = TestAndSet(&lock);

    waiting[i] = FALSE;  //what if I skip this??

    // 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);

4 个答案:

答案 0 :(得分:2)

你真的需要在第一次之后缩进该行。

" //关键部分"以下的内容将解锁等待访问的下一个任务,或者在没有人等待时释放锁定。

如果你没有清除你的等待标志,那么已经拥有锁定的另一项任务(可能是围绕他们访问受保护存储器运行相同的代码)会认为你还在等待并将清除你的等待标志让你运行(假设你正坐在循环中,检查TestAndSet,这是你的wait标志为真的唯一地方)。它保持锁定标志设置,因为它只是有效地将锁定传递给你。但是,如果您的代码实际上已经从那一点开始而没有设置值false,那么您无法在不将等待标志设置为True的情况下返回TestAndSet,并且由于锁定也保持为true,那么此任务可以& #39; t运行,其他任务没有运行,因为下一个任务没有得到批准(或者锁定没有设置为false),整个系统现在都是搞砸了。

答案 1 :(得分:0)

如果你跳过' ... = FALSE'这意味着你仍然在等待第一个while循环(对于特定的i)获取锁定(临界区)并且会破坏"循环的逻辑"访问第二个while循环中的临界区。

答案 2 :(得分:0)

消除那条线可能会破坏整个事情。它上面的两行是一个while循环,它可以在两个条件中的一个上终止 - waiting[i]变为假,或key变为假(或者两者同时"同时&# 34)。如果循环由于key为假而终止,那么waiting[i]可能仍然是真的,所以你会进入一个你同时持有锁并同时认为你还在等待锁的情况。可能违反了后续while循环的前提条件......

答案 3 :(得分:0)

我想我明白了。整个混乱是由do while()循环创建的,它包含整个代码。而不是这个做while()的东西,如果这些就像某个函数代表一个过程,如

function(int i)
{
  waiting[i] = TRUE;
  key = TRUE;

  while (waiting[i] && key)
    key = TestAndSet(&lock);

  waiting[i] = FALSE;  //what if I skip this??

  // 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
}

假设一个函数在i = 3的情况下被调用(比如过程i3。对于N = 5)。并且此过程i3永远不会再次执行,然后不设置等待[3] = false将最终陷入死锁状态。由于进程i4可能认为进程i3想要运行,因此最终会设置waiting [3] = false并且不释放锁