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

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

我想使用无锁实现。

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

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

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

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

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

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

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

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

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

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

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