【问题标题】:non-blocking thread-safe queue in C++?C ++中的非阻塞线程安全队列?
【发布时间】:2009-10-29 17:28:13
【问题描述】:

C++ 中是否有线程安全、非阻塞的队列类?

可能是一个基本的问题,但我已经很久没有做 C++了...

编辑:删除了 STL 要求。

【问题讨论】:

  • boost::lockfree::queue ?

标签: c++ thread-safety


【解决方案1】:

假设您的 CPU 具有双指针范围的比较和交换(compxchg8b 在 486 或更高版本上,compxchg16b 在大多数 amd64 机器上 [英特尔的一些早期型号上不存在])...有一个算法 @987654321 @。

更新:如果您不怕做一些工作,将其转换为 C++ 并不难。 :P

这个算法假设一个“带标签的指针”结构,如下所示:

// Be aware that copying this structure has to be done atomically...

template <class T>
struct pointer
{
   T *ptr;
   uintptr_t tag;
};

然后你想用一些内联汇编包装指令lock cmpxchg{8|16}b...

也许你可以这样写队列节点:

template <class T>
struct queue_node
{
    T value;
    pointer<queue_node<T> > next;
};

其余的或多或少是我链接到的算法的转录......

【讨论】:

  • @jldupont:-1 太讨厌了。 Asveikau 为您提供了一个很好的算法链接,只需几分钟即可将其转换为 C++。 -1 在这里完全不需要
  • ...这就是为什么我没有对他投反对票...只是给了他一个分数。如果您查看我的个人资料,您会发现我非常慷慨……您不会看到我投了很多反对票。
  • 基于危险指针的队列是另一种选择 - 它允许将未使用的内存释放回操作系统,而不必将其永久保留在空闲列表中。 research.ibm.com/people/m/michael/ieeetpds-2004.pdf 另请参阅 Relacy 以检查您的无锁算法:groups.google.com/group/relacy
  • 如果您实际上没有投反对票,为什么要说-1?这只是令人困惑。 :p
  • 现在是 2013 年,C++ 还没有标准的线程安全队列库?有多少开发者不得不重新编写同样的东西?
【解决方案2】:

由于当前的 C++ 标准甚至不承认线程的存在,所以在 STL 或标准库的任何其他部分中肯定没有线程安全的。

【讨论】:

  • 好吧:在 STL 之外怎么样?
  • 无论如何,标准保证不会是线程安全的。不过,真正的实现可以并且确实提供了自己的保证。
【解决方案3】:

这似乎是 Dobb 博士去年的热门话题:

【讨论】:

    【解决方案4】:

    您需要自己实现它或使用实现它的库。要自己做,你可能想看看这个:

    Implementing a Thread-Safe Queue using Condition Variables

    【讨论】:

    • 感谢您的链接。似乎这会给我的项目添加另一个依赖项:boost library。没有?
    • 没错。无论如何,如果您是 C++ 开发人员,您最终会使用 Boost。 Nikolai N Fetissov 关于 boost::mutex 的建议很好。
    • 作为一名 C++ 开发人员并不总能获得 Boost。我知道这里的每个人似乎都喜欢它,但很多项目都没有它(甚至禁止它)。看看 Chromium 是如何实现这一点的。
    • 政策问题,不多不少。
    • 条件变量总是与互斥锁一起使用。这不符合问题对非阻塞队列的要求。
    【解决方案5】:

    现在可能为时已晚。为了将来参考,这是一个很好的无锁队列实现(内置线程安全,有一些警告)。

    多生产者 - 多消费者

    http://moodycamel.com/blog/2014/a-fast-general-purpose-lock-free-queue-for-c++

    https://github.com/cameron314/concurrentqueue

    单一生产者 - 单一消费者

    http://moodycamel.com/blog/2013/a-fast-lock-free-queue-for-c++

    https://github.com/cameron314/readerwriterqueue

    【讨论】:

      【解决方案6】:

      简短的回答 - 不。 STL 本身不关心并发性(至少在规范级别上)。当前的 C++ 标准没有提到线程。

      不过,您可以轻松地在 STL 和 Boost 之上构建这样的队列 - 只需将 std::queueboost::mutex 包装在您的自定义类中。

      【讨论】:

      • 是通常打包在流行发行版中的提升,例如Ubuntu、Fedora?
      • 我想是的,至少在我的工作中安装的 vanilla RHEL 总是在 /usr/include 下有较旧的 Boost 版本。
      • 请记住,最初的问题是关于非阻塞队列。互斥锁是一种阻塞方式,因此不太可能符合条件。
      • 你可以随时尝试锁定和保释 - 这里没有阻塞:)
      • “当前 C++ 标准”——你能根据 C++11 更新你的答案吗?
      【解决方案7】:

      STL 容器不是线程安全的,您应该对并发访问实施处理。
      有这个项目 (C++) 旨在提供并发访问:CPH STL
      paper about

      【讨论】:

        【解决方案8】:

        目前非官方的Boost.Lockfree 值得考虑。我同时使用 FIFO 和 atomic 类型。

        【讨论】:

          猜你喜欢
          • 2019-02-12
          • 1970-01-01
          • 2010-10-22
          • 1970-01-01
          • 2014-10-16
          • 1970-01-01
          • 1970-01-01
          • 2017-09-13
          • 2019-11-01
          相关资源
          最近更新 更多