C:线程semaphore_wait vs while循环

时间:2011-01-20 08:59:36

标签: c pthreads while-loop semaphore processor

在处理器使用方面,以下代码段之间是否存在任何差异。

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

  while (someClass->ThreadIsAlive()) {

    while(someClass->isAsleep) { }

    someClass->isAsleep = true;

    //thread execution statements 

  }
  return argument;
}

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

OR

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 个答案:

答案 0 :(得分:3)

是的,第一个将导致处理器比第二个更多的工作。基本上,每当第一个示例中的活动线程被调度时,它将简单地占用在该条件下旋转的所有处理器时间,直到调度程序抢占它并给出另一个线程时间。这意味着您有上下文切换,并且线程的整个(可能)时间片每次都100%使用,实际上它不起作用。

第二个例子将线程捕获到内核中,因此在内核获取信号并恢复线程之前,它根本不会获得任何处理器时间。一旦发生这种情况,调度程序将再次给它处理时间,但现在我们知道它有实际的工作要做,而不是只使用它的整个时间片来固定CPU。

答案 1 :(得分:2)

典型的信号量实现将“停放”内核中的线程,因此它不使用处理器时间。因此强烈推荐:)

(类似地,大多数互斥实现都会执行此操作,但不会执行自旋锁)

答案 2 :(得分:2)

someClass->isAsleep为false时,您的第一个示例将在外循环中忙于旋转。也就是说,它会花费所有处理器时间来做任何事情。

你的第二个例子将在信号量上睡觉,而不是花费CPU时间。 即第一种情况非常非常糟糕,第二种情况很好。