C:线程 semaphore_wait 与 while 循环
以下代码片段在处理器使用方面有什么区别吗?
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 循环,该循环会阻塞直到满足条件(信号量的增量大于零)?
Is there any difference between the following pieces of code in terms of processor usage.
void *ManageSequencer(void *argument){
SomeClass *someClass = (SomeClass *)argument;
while (someClass->ThreadIsAlive()) {
while(someClass->isAsleep) { }
someClass->isAsleep = true;
//thread execution statements
}
return argument;
}
where some class sets isAsleep=false
periodically when it needs the thread to execute
OR
void *ManageSequencer(void *argument){
SomeClass *someClass = (SomeClass *)argument;
while (someClass->ThreadIsAlive()) {
semaphore_wait(sem);
//thread execution statements
}
return argument;
}
where someClass calls semaphore_signal(sem);
periodically when it needs the thread to execute.
this question is not about atomicity, just whether the while loop will cause the processor more work than the semaphore solution. Does the semaphore just have a while loop inside it that blocks until a condition is met (increment of semaphore above zero)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
是的,第一个会导致处理器比第二个做更多的工作。基本上,每当第一个示例中的活动线程被调度时,它就会耗尽在该条件下旋转的所有处理器时间,直到调度程序抢占它并给另一个线程时间。这意味着您有上下文切换,并且线程的整个(可能)时间片每次都被 100% 使用,但实际上没有任何作用。
第二个示例将线程捕获在内核中,因此在内核获取信号并恢复线程之前,它根本不会获得任何处理器时间。一旦发生这种情况,调度程序将再次为其提供处理时间,但现在我们知道它有实际的工作要做,而不仅仅是使用与 CPU 挂钩的整个时间片。
Yes, the first one will cause the processor much more work than the second. Basically, whenever the active thread in the first example gets scheduled, it will simply eat up all of its processor time spinning on that condition until the scheduler preempts it and gives another thread time. This means you have context switches and the thread's entire (potentially) time slice is used 100% every time and it actually does no work.
The second example will trap the thread in the kernel, so it won't get any processor time at all until the kernel gets the signal and resumes the thread. Once that happens, the scheduler will give it processing time again, but now we know it has actual work to do instead of just using its entire time slice pegging the CPU.
典型的信号量实现会将线程“停放”在内核中,这样它就不会占用处理器时间。因此强烈建议:)
(同样,大多数互斥锁实现都会这样做,但自旋锁不会)
A typical semaphore implementation will "park" the thread in the kernel so it's not using processor time. Strongly recommended for that reason :)
(similarly, most mutex implementations will do this, but spinlocks will not)
当
someClass->isAsleep
为 false 时,您的第一个示例将在外循环中忙于旋转。即,它将花费所有给定的处理器时间什么都不做。您的第二个示例将在信号量上进入休眠状态,而不花费 CPU 时间。
也就是说,第一种情况非常非常糟糕,第二种情况很好。
Your first example is going to busy spin in the outer loop when
someClass->isAsleep
is false. i.e., it'll spend all processor time given on doing nothing.Your second example will be put to sleep on the semaphore and not spend CPU time.
I.e. the first case is very, very bad, the second case is good.