【问题标题】:Queue with lock vs Lock Free Queue带锁队列与无锁队列
【发布时间】:2017-04-21 03:17:05
【问题描述】:

我参与了一项侦听网络服务的任务。它将通过推送服务发送一个 xml 数据。数据必须经过一些计算,然后我们才会显示出来。

我计划使用队列来存储服务监听器的数据,并通过业务逻辑代码读取数据。是纯单生产者单消费者队列。

由于我必须以 Web 服务推送的形式接收数据,因此我必须始终打开以接收数据并将其推送到队列中。我想过使用boost_lockfree_spsc_queue。因为,如果它是一个可锁定队列,则监听器必须等待一段时间才能获得锁,而 boost_lockfree_spsc_queue 不需要任何锁。

我要存储的数据是

struct MemoryStruct {
    char *memory;
    size_t size;
};

而队列是

boost::lockfree::spsc_queue<MemoryStruct*> lockFreeQ{100};

在这里阅读性能部分后,我有点困惑。

将此 boost_lockfree_spcc_queue 用于生产目的是否安全。还是应该使用带锁的标准队列(C++ 11)?

谢谢

【问题讨论】:

  • 是的,它可以安全地用于生产用途 - 只要您遵守使用要求。哪个部分让你感到困惑?
  • 您使用MemoryStruct 但担心boost 会搞砸您的程序?
  • 使用 MemoryStruct 有什么问题吗?
  • stackoverflow.com/users/85371/sehe(http://www.boost.org/doc/… ) 在讨论非阻塞数据结构的性能时,必须区分摊销成本和最坏情况成本。 'lock-free' 和 'wait-free' 的定义只提到了操作的上限。因此,无锁数据结构不一定是每个用例的最佳选择。为了最大化应用程序的吞吐量,应该考虑高性能并发数据结构

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


【解决方案1】:

是的。如果您希望负载不会使您的 CPU 饱和,您只会增加电费。通常的方法是指数回退。 ¹

如果您对此完全不确定,那么这听起来很像过早优化,您可能可以使用锁定队列。

您可以确保您的使用模式可以轻松地在无锁实现中进行交换。制作您自己的阻塞 pop() 函数,该函数将在无锁实现的情况下包装等待逻辑。

¹ 参见例如http://kukuruku.co/hub/cpp/lock-free-data-structures-the-evolution-of-a-stack

【讨论】:

  • 很抱歉,我对您的声明“制作您自己的阻塞 pop() 函数,该函数将在无锁实现的情况下包装等待逻辑”有点不清楚。
  • 自己预订 pop() 意味着使用 lock() 和 unlock() 包围 pop()。在无锁情况下包装等待逻辑是什么意思?无锁意味着等待免费吗?那我为什么要使用等待逻辑来扭曲无锁实现呢?
  • TL;DR 使用锁定队列。或者,玩弄无锁队列,以便您看到界面中的差异(例如,没有size()empty() 调用)。如果您发现自己毕竟需要一个,这将使您在未来的版本中更容易迁移到无锁队列。只是,一步一个脚印。查看您确实了解的内容,一步​​一步地扩展您的知识 - 跟随您的好奇心。跳跃只会导致您的经验/理解出现漏洞。
  • 回复。 “制作我自己的预订 pop() 意味着使用 lock() 和 unlock() 包围 pop()”——当然不是。这将通过同步外部访问来使用未锁定的队列。这不是阻塞队列的作用。它在内部锁定。 忘记我的包装建议,请参阅之前的评论。
  • 您好,感谢您的回复并向我介绍这些术语。我会阅读更多相关信息并回来。
猜你喜欢
  • 2013-04-22
  • 2011-08-30
  • 1970-01-01
  • 2018-06-30
  • 1970-01-01
  • 2011-08-30
  • 2010-12-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多