我正在设计一个新的改进的Logger组件(.NET 3.5,C#)。
我想使用一个无锁的实现。
日志事件将从(潜在)多个线程发送,尽管只有一个线程将实际输出到文件/其他存储介质。
本质上,所有的写入器都将其数据排队到某个队列中,由其他进程(LogFileWriter)检索。
这能以无锁的方式实现吗?我在网上找不到直接提到这个问题的地方。
发布于 2012-01-05 01:20:35
如果您发现在这种情况下使用锁太慢,那么您有一个更大的问题。锁,当它没有竞争时,在我的系统上大约需要75纳秒(2.0 GHz Core2Quad)。当然,当它被争夺的时候,它将需要更长的时间。但是,由于锁只是保护对Enqueue或Dequeue的调用,日志写入的总时间不太可能超过75纳秒。
如果锁是一个问题--也就是说,如果您发现线程排在锁后面,并在应用程序中造成明显的减速--那么创建一个无锁队列是不太可能有多大帮助的。为什么?因为如果您真的要给日志写那么多东西,那么您的无锁阻塞队列就会填满得太快,以至于限制在I/O子系统的速度上。
我有一个多线程应用程序,它每秒向受简单锁保护的Queue<string>写入200个日志条目。我从来没有注意到任何重要的锁争用,而且处理速度丝毫没有减慢。75 ns与完成其他所有事情所需的时间相比都显得矮小。
发布于 2012-01-05 00:02:20
这种无锁队列的实现可能会很有帮助,其中队列是您用来将要退出队列的项排队并由记录器写出的数据结构。
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
发布于 2012-01-05 15:18:21
有很多不同的无锁队列的实现。
我自己在http://hackcraft.github.com/Ariadne/使用的是一种简单的方法,并且是开源的,因此您可以在必要时对其进行调整。
ConcurrerntQueue也是无锁的,并且可能能很好地满足大多数目的,尽管在Ariadne中有几个成员支持其他操作(比如将整个内容的枚举去排队作为原子操作,这允许单个使用者进行更快的枚举)。
https://stackoverflow.com/questions/8735800
复制相似问题