C:线程信号量的semaphore_wait和while循环的区别

5
以下代码在处理器使用方面有什么区别吗?
void *ManageSequencer(void *argument){
  SomeClass *someClass = (SomeClass *)argument;

  while (someClass->ThreadIsAlive()) {

    while(someClass->isAsleep) { }

    someClass->isAsleep = true;

    //thread execution statements 

  }
  return argument;
}

在一些类中,当需要线程执行时,会定期设置isAsleep=false

或者

void *ManageSequencer(void *argument){
  SomeClass *someClass = (SomeClass *)argument;

  while (someClass->ThreadIsAlive()) {

    semaphore_wait(sem);

    //thread execution statements 

  }
  return argument;
}

当someClass需要线程执行时,它会定期调用semaphore_signal(sem);

这个问题与原子性无关,只是想知道while循环是否会比信号量解决方案导致处理器更多的工作。信号量内部是否只有一个while循环,一直阻塞直到条件被满足(信号量增加到大于零)?

3个回答

4
是的,第一个示例会比第二个示例让处理器工作更多。基本上,当第一个示例中的活动线程被调度时,它将仅在该条件上旋转,直到调度程序抢占它并给另一个线程时间为止,这意味着您需要进行上下文切换,并且线程的整个(可能)时间片每次都被100%使用,实际上不做任何工作。
第二个示例将使线程陷入内核中,因此它将不会获得任何处理器时间,直到内核收到信号并恢复线程。一旦发生这种情况,调度程序将再次为其分配处理时间,但现在我们知道它有实际工作要做,而不仅仅是使用其整个时间片来卡住CPU。

2
一种典型的信号量实现会将线程“停放”在内核中,以便不占用处理器时间。因此强烈建议使用此方法 :) (类似地,大多数互斥锁实现也会这样做,但自旋锁则不会)。

2

someClass->isAsleep为false时,您的第一个示例将在外部循环中忙碌自旋,也就是说,它会花费所有给定的处理器时间来无所事事。

您的第二个示例将被放置在信号量上睡眠,而不会花费CPU时间。也就是说,第一种情况非常糟糕,而第二种情况则很好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接