信号量 wait() 函数中 while 循环的目的是什么?可以用if语句代替吗?

What is the purpose of the while loop in semaphore wait( ) function? Can it be replaced with an if statement?

我正在学习操作系统中的信号量,但我不明白空 while 循环的用途。

代码来自我的教科书,我可以看到 while(s <= 0) 后跟一个 ';'所以基本上是:什么都不做,然后是 s-- 行。 我不明白这样做的目的或意义,如果是 if(s <= 0) 而不是 while 会有什么不同吗?

wait (S) {
    while S <= 0
    ; //no-op
    S--; 
}

信号量是一个计数器,您可以在其上调用两个函数:decrement(也称为 waitp 等)和 incrementpostsignalv 等)。

线程在信号量上调用 wait 时会发生以下情况:

  1. 如果信号量计数大于 0,则计数减 1 并调用 wait returns
  2. 如果信号量计数小于或等于0,对wait的调用将等待信号量计数增加到1或更多(当其他线程调用post时会发生这种情况)在信号量上),从计数中减去 1,并且 return

上面代码中的while循环是为了处理第二种情况。函数一定不能return直到计数大于0(这就是循环条件为S <= 0的原因),所以while循环会一直旋转直到这个计数大于0。目的while 循环只是为了阻止函数前进。没有您想重复执行的代码体。

if 语句不足以处理这种情况,因为它只检查 S <= 0 一次。即使计数仍然小于或等于 0,该函数也能够前进到 if 语句。

请注意,您教科书中的信号量代码大大简化了实际信号量的工作方式。通常,如果一个线程调用 wait 并且计数小于或等于 0,则该线程将让出,调度程序将使该线程休眠,直到另一个线程调用 post。因此,要么没有 while 循环,要么存在的任何 while 循环都与您的问题中的循环略有不同。此外,信号量结构中的整数计数器需要某种保护机制。否则,多个线程可以争用 increment/decrement 这个计数器,并且即使计数最初为 1,多个线程也可以通过 while 循环(因此信号量不会正确保护临界区)。