是否存在多个读取或写入线程的无锁队列?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了是否存在多个读取或写入线程的无锁队列?相关的知识,希望对你有一定的参考价值。

我在想,当多个线程正在读写时,是否有可能拥有无锁队列?我已经看到了一个带有无锁队列的实现,它可以使用一个读取线程和一个写入线程但不会超过一个。可能吗?我认为不是。可以/有人想要证明吗?

答案

有多种算法可用,我最终实现了An Optimistic Approach to Lock-Free FIFO Queues,它通过指针标记避免了ABA问题(需要CMPXCHG8B上的x86指令),并且它在生产应用程序(用Delphi编写)中运行良好。 (Another version, with Java code

然而,要真正无锁,你还需要一个无锁内存分配器 - 参见Scalable Lock-Free Dynamic Memory Allocation(在Concurrent Building Block中实现)或NBMalloc(但到目前为止,我没有使用其中一个)。

您可能还想查看optimistic lock-free FIFO queues impl?的答案

另一答案

Java的无锁队列实现允许读写。这项工作是通过比较和设置操作(这是一个单CPU指令)完成的。

ConcurrentLinkedQueue使用一种方法,在这种方法中,线程可以帮助彼此从队列中读取(或轮询)对象。由于它是链接的,队列的头部可以接受写入,而队列的尾部可以接受读取(假设有足够的空间)。所有这些都可以并行完成,并且完全是线程安全的。

另一答案

使用.NET 4.0,有ConcurrentQueue(T) Class。 简而言之,根据C#4.0,这是一个无锁实现。另见blog entry

另一答案

您并不特别需要锁,而是从队列中删除内容的原子方法。没有锁定和原子test-and-set指令也可以这样做。

另一答案

Primoz Gabrijelcic(Delphi Geek)在OmniThreadLibrary中有一个动态锁定免费队列:http://www.thedelphigeek.com/2010/02/omnithreadlibrary-105.html

另一答案

使用.NET 4.0,有ConcurrentQueue Class

Sample

https://dotnetfiddle.net/ehLZCm

public static void Main()
{
    PopulateQueueParallel(new ConcurrentQueue<string>(), 500);
}

static void PopulateQueueParallel(ConcurrentQueue<string> queue, int queueSize)
{
    Parallel.For(0, queueSize, (i) => queue.Enqueue(string.Format("my message {0}", i)));
    Parallel.For(0, queueSize,
        (i) =>
        {
            string message;
            bool success = queue.TryDequeue(out message);
            if (!success)
                throw new Exception("Error!");

            Console.WriteLine(message);
        });
}

以上是关于是否存在多个读取或写入线程的无锁队列?的主要内容,如果未能解决你的问题,请参考以下文章

多线程编程之无锁队列

带危险指针的无锁内存回收

支持内部晋升的无锁并发优先级线程池

在 Folly 的无锁 SPSC 队列中使用 std::memory_order_consume

linux内核无锁缓冲队列kfifo原理

基于共享内存的无锁消息队列设计