忙碌的等待是这样的:
for(;;) {
if (condition) {
break;
}
}
条件可以是“检查当前时间”(例如性能计数器轮询)。有了这个,您可以在线程中获得非常准确的暂停。这对于例如低级 I/O(切换 GPIO 等)很有用。因此,您的线程一直在运行,并且如果您使用协作多线程,则您完全可以控制线程将等待您多长时间。通常这种线程具有高优先级并且是不可中断的。
现在一个不忙的等待意味着,线程是不忙的。它允许另一个线程执行,所以有一个上下文切换。要允许上下文切换,在大多数语言和操作系统中,您可以简单地使用 sleep()。还有其他类似的函数,如 yield()、wait()、select() 等。它取决于操作系统和语言,如果它们是非忙或忙实现。但根据我的经验,在所有情况下,睡眠 > 0 总是不忙。
非忙等待的优点是允许其他线程运行,其中包括空闲线程。有了这个,您的 CPU 可以进入省电模式、时钟下降等。它还可以运行其他任务。在指定时间之后,调度程序会尝试返回您的线程。但这只是一种尝试。这并不准确,可能比您的睡眠定义的时间长一点。
我想。现在很清楚了。
现在最大的问题是:这是忙还是非忙等待:
for(;;) {
if (condition) {
break;
}
sleep(1);
}
答案是:是非忙等待。 sleep(1) 允许线程执行上下文切换。
现在下一个问题:第二个 for() 是忙,还是非忙等待:
function wait() {
for(;;) {
if (condition) {
break;
}
}
}
for(;;) {
wait();
if (condition) {
break;
}
sleep(1);
}
很难说。这取决于 wait() 函数的实际执行时间。如果它什么都不做,那么 CPU 几乎整个时间都在 sleep(1) 中。这将是一个非阻塞的 for 循环。但是如果wait()是一个繁重的计算函数,不允许线程上下文切换,那么这整个for循环可能会变成一个阻塞函数,即使有sleep(1)。想想最坏的情况:wait() 函数永远不会返回给调用者,因为很长一段时间都没有满足条件。
这里很难回答,因为我们不知道条件。您可以通过以下方式想象问题,您无法回答问题,因为您不知道条件:
if (unkonwnCondition) {
for(;;) {
if (condition) {
break;
}
}
} else {
for(;;) {
if (condition) {
break;
}
sleep(1);
}
}
如你所见,它是一样的:因为你不知道条件,你不能说等待是忙还是不忙。