在处理器使用方面,以下代码段之间是否存在任何差异。
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循环阻塞直到满足条件(信号量增加到零以上)?
答案 0 :(得分:3)
是的,第一个将导致处理器比第二个更多的工作。基本上,每当第一个示例中的活动线程被调度时,它将简单地占用在该条件下旋转的所有处理器时间,直到调度程序抢占它并给出另一个线程时间。这意味着您有上下文切换,并且线程的整个(可能)时间片每次都100%使用,实际上它不起作用。
第二个例子将线程捕获到内核中,因此在内核获取信号并恢复线程之前,它根本不会获得任何处理器时间。一旦发生这种情况,调度程序将再次给它处理时间,但现在我们知道它有实际的工作要做,而不是只使用它的整个时间片来固定CPU。
答案 1 :(得分:2)
典型的信号量实现将“停放”内核中的线程,因此它不使用处理器时间。因此强烈推荐:)
(类似地,大多数互斥实现都会执行此操作,但不会执行自旋锁)
答案 2 :(得分:2)
当someClass->isAsleep
为false时,您的第一个示例将在外循环中忙于旋转。也就是说,它会花费所有处理器时间来做任何事情。
你的第二个例子将在信号量上睡觉,而不是花费CPU时间。 即第一种情况非常非常糟糕,第二种情况很好。