是否存在多个读取或写入线程的无锁队列?
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);
});
}
以上是关于是否存在多个读取或写入线程的无锁队列?的主要内容,如果未能解决你的问题,请参考以下文章