while(true) vs wait+condition synchronism

while(true) vs wait+condition synchronism

本文关键字:wait+condition synchronism vs true while      更新时间:2023-10-16

把线程放在while(true)循环中并测试条件是否可以开始治疗是一种不好的做法吗?

void run()
{
    for(;;)
    {
        if(dataReady)
        {
            processData();
        }
    }
}

是否更适合使用等待/条件机制:

void run()
{
    for(;;)
    {
        if(dataReady)
        {
            processData();
        }
        lock_guard lock(mutex);
        condition_.wait(lock);
    }
}
另一个线程当然调用condition_.notify_one() 编辑:

而true是一个不好的方式,因为它只占用处理周期。
第二种方法更好,只有当线程必须执行某些工作时才会提示。

这取决于您预计等待的时间。

对于非常短的时间,繁忙等待是可取的,因为它不像其他技术那样涉及上下文切换。上下文切换的开销有时可能会超过整个busy-wait循环。

如果采用第一种方法,则需要确保编译器实际上是从内存中读取变量,而不是优化从内存中读取的变量,因为值不能在循环中更改。要做到这一点,必须将变量声明为"volatile"。

但这本身是不够的。您需要某种形式的内存屏障来确保在一个线程中对变量的更改对另一个线程可见,并且存储和读取不会被CPU和缓存重新排序。如果这是在x86上,您可能不需要它。但是如果你想做这种事情,你最好使用编译器的内在特性,如InterlockedIncrement(在windows上,或类似的在其他平台上)。

在几乎所有情况下,你最好使用条件变量,或者从库中使用自旋锁(这基本上是你想要实现的),因为它们将为多核处理获得正确的细节。

建议采用后一种方法。但是这是任何线程或并发论文中的一个基本问题…

在较旧的处理器中,只有一个线程,并且无论处理器在做什么都要消耗电源,等待是一种常见的习惯用法。现在处理器有几个线程可以推进,而且它们也足够智能,如果你只是在等待一个条件,它们就不会消耗能量。

前者通常是一个糟糕的主意,因为您将在一个核心上使用100%的CPU,而什么也不做。您将消耗掉本可以由其他线程使用的资源(可能是应该设置dataready的线程)。

在第二个示例中,线程被保持直到收到通知。所以它不会占用CPU时间。

是的,这是不好的做法。只有在锁和线程等复杂结构不可用的地方,繁忙循环才是合理的设计选择。

虽然,如果你能保证你的软件是设备上唯一运行的应用程序(可能是嵌入式项目的情况),你可能会求助于忙循环。