【问题标题】:Implementing a multiple producer/consumer lockless queue in C\C++在 C\C++ 中实现多生产者/消费者无锁队列
【发布时间】:2012-01-12 09:08:28
【问题描述】:

我已经在一个无锁队列上的单个生产者/消费者上完成了我的基本实现,它运行良好。但是,当我尝试将其扩展到多个生产者/消费者时,我开始遇到冲突。我通过 SO 找到了一篇与此问题相关的类似帖子 (Is there such a thing as a lockless queue for multiple read or write threads?),并且我发现了一篇文章对原始实现进行了更深入的介绍。我也对这篇文章感到困惑,希望得到一些指导。

首先是这个实现在使用多个生产者/消费者时是否真的有效,或者在与多个生产者/消费者设置一起工作的原始 Michael-Scott 实现中是否缺少某些东西。

第二个是在An Optimistic Approach to Lock-Free FIFO Queues 文章中的 Dequeue 部分显示了一个虚拟值的使用。如何确定要使用的适当值?如果我使用整数,什么能让我确定我为虚拟值选择的整数不是我决定排队的实际值?

任何建议或总体方向都会很棒。如果有人想知道我正在 Visual Studio 中创建它,以便更好地理解非阻塞算法。我想让它尽可能通用,以便我可以排队任何想要的东西(队列中的数据是模板化的,因此用户可以指定要排队的内容)。

【问题讨论】:

  • 也许this article 感兴趣。
  • 我一直觉得无锁环形缓冲区最适合支持 LL-FIFO(仍然不确定它们有多安全,忙于测试我的一些想法 atm)。
  • @KerrekSB:我在找那篇文章。谢谢
  • @KerrekSB:读完那篇文章后,我有几个问题,也许你可以澄清一下。这提到了临界区和自旋锁的使用,所以通常这仍然使用一种锁。在这种情况下,我们必须有一个锁吗?是否有,目前没有安全锁少多生产者/消费者算法?
  • @Seb:所讨论的“锁”只是一个本地锁,它保护一个非常短的操作,即两个指针的更新。在这种情况下,旋转不是问题,因为您不会旋转很长时间,而且忙碌的等待可能比任何其他会触发上下文切换的锁更快。您不能没有某种 类同步,并且由于通常没有用于关键部分的原子硬件原语,因此自旋锁是一个合适的解决方案...

标签: c++ multithreading queue nonblocking


【解决方案1】:

提防邪恶:ABA problem

您可以开始阅读thisthisthis

【讨论】:

    【解决方案2】:

    您可以制作一个廉价的包装器类型,以便您可以跟踪项目的有效性,并且用户可以透明地传递值而无需担心它。这会产生一些小的内存开销,但如果您想允许空值的入队和出队(而不是将它们视为“虚拟”哨兵),则没有更好的方法。

    例子:

    template<typename T>
    class MyQueue
    {
        /* . . . */
    public:
        void Enqueue(T * value)
        {
            MyQueueItem item;
            item.value = value;
            item.isValid = true;
    
            /* enqueue it now
               . . . */
        }
    
        T * Dequeue()
        {
            MyQueueItem validItem;
            /* Get the first element where isValid == true
               . . . */
            return validItem.value;
        }
    
    private:
        struct MyQueueItem
        {
            T * value;
            bool isValid;
        };
    };
    

    【讨论】:

      【解决方案3】:

      没有明确支持在 C++ 中实现非阻塞队列所需的原子 cpu 指令(不过,它在较新的规范中)。

      您可以访问您机器上的说明,但您必须内联一些程序集或找到一个库(TBB 或 boost)来为您完成。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-10-31
        • 1970-01-01
        • 1970-01-01
        • 2011-02-11
        • 1970-01-01
        • 2011-08-30
        • 2010-10-18
        • 1970-01-01
        相关资源
        最近更新 更多