1

我打算为我的多线程应用程序使用boost::lockfree::queue 。一个boost 示例说明了无锁队列的消耗,如下所示:

boost::atomic<bool> done (false);
void consumer(void)
{
    int value;
    while (!done) {
        while (queue.pop(value))
            ++consumer_count;
    }

    while (queue.pop(value))
        ++consumer_count;
}

我的问题是这部分:

    while (!done) {
    //do something
    }

我通常用于condition variable这种情况,但上述代码片段的简单性远比条件变量的复杂性更具诱惑力。

尽管consumer将有自己的线程,但它几乎在整个程序期间循环。我更担心,因为很多时候该//do something部分没有被调用(队列为空),并且可以给其他线程的大量CPU时间被这个线程浪费了。我对吗?这是一种常见的做法吗?

我需要有人告诉我我错了,我不应该因为这样的原因而担心这个。或建议我更好的方法。

谢谢

4

2 回答 2

2

忙等待的效率是否高于阻塞取决于您平均要等待多长时间。一些循环迭代可能比上下文切换更快。

使用无锁队列的要点是,它是无锁的。如果要阻止,最好按照您的建议将条件变量与另一个队列一起使用。

于 2014-08-04T09:34:02.287 回答
2

对于延迟敏感的应用程序,即唤醒线程所花费的时间不可接受的应用程序,这是一种非常常见的做法。

是的,在这种情况下(称为“旋转”),CPU 时间被浪费在检查布尔值上。自旋锁以类似的方式实现,使其更适合于忙等待的场景。

当生产者到消费者路径的延迟不重要时,您应该更喜欢条件变量(甚至显式休眠)与其他线程/进程共享 CPU。无论如何,当延迟很关键时,您很少需要无锁容器(通常会暴露大量开销以避免锁定)

于 2014-08-04T09:44:42.040 回答