实现无锁队列(对于Logger组件)

时间:2012-01-04 23:51:14

标签: c# .net multithreading concurrency lockless

我正在设计一个新的改进的Logger组件(.NET 3.5,C#)。

我想使用无锁实现。

记录事件将从(可能)多个线程发送,但只有单个线程将实际输出到文件/其他存储介质。

本质上,所有的编写者都将他们的数据排入某个队列,然后通过其他一些进程(LogFileWriter)进行检索。

这可以通过无锁方式实现吗?我无法在网上找到这个特定问题的直接参考。

3 个答案:

答案 0 :(得分:13)

如果您发现在这种情况下使用锁定太慢,则会出现更大的问题。锁定,当它没有争用时,在我的系统上需要大约75纳秒(2.0 GHz Core 2 Quad)。当它争论时,当然,它需要更长的时间。但由于锁只是保护对EnqueueDequeue的调用,因此日志写入的总时间不可能远远超过75纳秒。

如果锁 是一个问题 - 也就是说,如果你发现你的线程排在该锁后面并导致你的应用程序显着减速 - 那么就不可能建立一个无锁队列会有很大的帮助。为什么?因为如果你真的那么多地写入日志,你的无锁阻塞队列将会如此迅速地填满,你将被限制在I / O子系统的速度。

我有一个多线程应用程序,每秒写入200个日志条目的顺序到Queue<string>,受到简单锁定的保护。我从来没有注意到任何明显的锁争用,并且处理速度不会太慢。 75 ns与其他所有事情相比已经相形见绌了。

答案 1 :(得分:5)

这种无锁队列的实现可能会有所帮助,其中队列是您用来将要出列的项目入队并由记录器写出的数据结构。

http://www.boyet.com/Articles/LockfreeQueue.html

您也可以查看.Net 4的ConcurrentQueue

http://www.albahari.com/threading/part5.aspx#_Concurrent_Collections

http://geekswithblogs.net/BlackRabbitCoder/archive/2011/02/10/c.net-little-wonders-the-concurrent-collections-1-of-3.aspx

答案 2 :(得分:0)

那里有无锁队列的不同实现。

我自己在http://hackcraft.github.com/Ariadne/使用了一种简单的方法,并且是开源的,因此您可以根据需要进行调整。

ConcurrerntQueue也是无锁的,并且很可能用于大多数目的,尽管在Ariadne中有一些成员支持其他操作(例如将整个内容的枚举作为原子操作出列,允许单个消费者更快的枚举。)