我打算将boost::lockfree::queue用于我的多线程应用程序。 boost example说明了无锁队列消耗,如下所示:
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时间。我对吗? THIS是一种常见做法吗?
我需要有人告诉我我错了,我不应该因为这么原因而担心这件事。 要么 建议我一个更好的方法。
感谢
答案 0 :(得分:2)
如果忙碌等待的效率高于或低于阻止取决于您平均等待多长时间。一些循环迭代可能比上下文切换更快。
使用无锁队列的关键是,它是无锁的。如果要阻止,最好按照建议使用条件变量和另一个队列。
答案 1 :(得分:2)
对于延迟敏感的应用程序来说,这是一种非常常见的做法,即用于唤醒线程的时间不可接受的应用程序。
是的,在这种情况下(称为&#34;旋转&#34;),CPU时间被浪费以检查布尔值。 Spinlocks以类似的方式实现,在首选繁忙等待的情况下更适合。{/ p>
当生产者到消费者路径的延迟并不重要时,您应该更喜欢条件变量(甚至是显式休眠)来与其他线程/进程共享CPU。无论如何,当延迟很关键时,你很少需要一个无锁的容器(这通常会产生很大的开销以避免锁定)