boost c ++无锁队列vs共享队列

时间:2013-04-29 09:20:13

标签: c++ multithreading boost producer-consumer lock-free

我是多线程编程的新手,我只知道最常见的Producer-Consumer-Queue。 我正在使用boost c ++库,我不知道是否更好地使用boost :: lockfree :: queue或使用`mutex`和`condition_variable`的std :: queue周围的包装类。

哪里更好地使用无锁数据结构哪里更好是使用基于`mutex`和`condition_variables`的简单实现?

4 个答案:

答案 0 :(得分:17)

在您的应用中同时尝试,看看效果最佳。

通常,当队列几乎总是有条目时,轮询无锁队列最有效,当队列几乎总是空的时,阻塞队列效果最好。

由于内核信令,阻塞队列的缺点是延迟,通常约为2-20 uS。这可以通过设计系统来减轻,以便消费者线程在每个排队项目上完成的工作所花费的时间比这个时间间隔长得多。

非阻塞队列的缺点是在轮询空队列时浪费CPU和内存带宽。这可以通过设计系统来减轻,以便队列很少是​​空的。

正如评论者已经暗示的那样,非阻塞队列在单CPU系统上是个坏主意。

答案 1 :(得分:9)

(补充)

从1.54开始,您应该了解一些要求

boost::lockfree::queue

  • T必须有一个复制构造函数
  • T必须有一个简单的赋值运算符
  • T必须有一个简单的析构函数

boost::lockfree::stack

  • T必须有一个复制构造函数

boost::lockfree::spsc_queue

  • T必须具有默认构造函数
  • T必须是可复制的

答案 2 :(得分:3)

您还可以使用无锁队列来避免实时应用程序中的优先级倒置

例如,Android上的OpenSL在高优先级线程上提供音频缓冲区队列回调。如果此线程必须等待较低优先级线程持有的锁,则其高优先级调度无效,回调变得不规则,并且您可能开始欠载音频缓冲区 - 这会导致一些令人不快的弹出声音。

答案 3 :(得分:1)

决定归结为提问:“锁定争用会成为要解决的任务的问题吗?”

锁定在并发环境中解决了两个不同的问题

  • 正确性:确保代码实际执行预期的操作。防止来自其他线程的干扰。
  • 吞吐量/可扩展性:允许通过系统的并发操作的持续高“流”。允许通过添加更多资源来扩展系统性能。

这两个问题是对立的目标。 经典方法是使用全局锁来保护共享数据结构。这可以确保100%的正确性,但是它会阻止性能,尤其是并发级别在一定程度上扩展,因为共享锁会导致“流量拥塞”

顺便说一下,使用“无锁”一词时需要小心。严格地说,协作操作永远不会100%无锁。但是可以巧妙地安排协作,以便减少阻止对那些真正需要同时访问同一元素的合作伙伴的影响。