简体   繁体   English

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

[英]Implementing a lock-free queue (for a Logger component)

I am designing a new improved Logger component (.NET 3.5, C#). 我正在设计一个新的改进的Logger组件(.NET 3.5,C#)。

I would like to use a lock-free implementation. 我想使用无锁实现。

Logging events will be sent from (potentially) multiple threads, although only a single thread will do the actual output to file/other storage medium. 记录事件将从(潜在地)多个线程被发送,尽管只有一个线程将执行实际输出到文件/其它存储介质。

In essence, all the writers are * enqueuing* their data into some queue, to be retrieves by some other process (LogFileWriter). 从本质上讲,所有的编写器都将它们的数据排入某个队列,然后通过其他一些进程(LogFileWriter)进行检索。

Can this be achieved in a lock-less manner? 这可以通过无锁方式实现吗? i could not find a direct reference to this particular problem on the net. 我无法在网上找到这个特定问题的直接参考。

If you find that using a lock in this case is too slow, you have a much bigger problem. 如果您发现在这种情况下使用锁定太慢,则会出现更大的问题。 A lock, when it's not contended, takes about 75 nanoseconds on my system (2.0 GHz Core 2 Quad). 锁定,当它没有争用时,在我的系统上需要大约75纳秒(2.0 GHz Core 2 Quad)。 When it's contended, of course, it's going to take somewhat longer. 当它争论时,当然,它需要更长的时间。 But since the lock is just protecting a call to Enqueue or Dequeue , it's unlikely that the total time for a log write will be much more than that 75 nanoseconds. 但由于锁只是保护对EnqueueDequeue的调用,因此日志写入的总时间不可能远远超过75纳秒。

If the lock is a problem--that is, if you find your threads lining up behind that lock and causing noticeable slowdowns in your application--then it's unlikely that making a lock-free queue is going to help much. 如果锁一个问题 - 也就是说,如果你发现你的线程排在该锁后面并导致你的应用程序显着减速 - 那么建立一个无锁队列就不太可能有所帮助。 Why? 为什么? Because if you're really writing that much to the log, your lock-free blocking queue is going to fill up so fast you'll be limited to the speed of the I/O subsystem. 因为如果你真的那么多地写入日志,那么你的无锁阻塞队列将会如此快地填满,你将被限制在I / O子系统的速度上。

I have a multi-threaded application that writes on the order of 200 log entries a second to a Queue<string> that's protected by a simple lock. 我有一个多线程应用程序,每秒写入200个日志条目的顺序到一个受简单锁保护的Queue<string> I've never noticed any significant lock contention, and processing isn't slowed in the least bit. 我从来没有注意到任何明显的锁争用,并且处理速度不会太慢。 That 75 ns is dwarfed by the time it takes to do everything else. 75 ns与其他所有事情相比已经相形见绌了。

This implementation of a lock free queue might be helpful, where the queue is the data structure you'd use to enqueue the items to be dequeued and written out by the logger. 这种无锁队列的实现可能会有所帮助,其中队列是您用于将要出列的项目入队并由记录器写出的数据结构。

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

You might also look at .Net 4's ConcurrentQueue 您也可以查看.Net 4的ConcurrentQueue

http://www.albahari.com/threading/part5.aspx#_Concurrent_Collections 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://geekswithblogs.net/BlackRabbitCoder/archive/2011/02/10/c.net-little-wonders-the-concurrent-collections-1-of-3.aspx

There's quite a few different implementations of lock-free queues out there. 那里有无锁队列的不同实现。

My own at http://hackcraft.github.com/Ariadne/ uses a simple approach, and is open source so you can adapt it if necessary. 我自己在http://hackcraft.github.com/Ariadne/上使用了一种简单的方法,并且是开源的,因此您可以根据需要进行调整。

ConcurrerntQueue is also lock-free, and will probably serve most purposes fine, though that in Ariadne has a few members supporting other operations (like dequeuing an enumeration of the entire contents as an atomic operation, which allows for faster enumeration by a single consumer). ConcurrerntQueue也是无锁的,并且很可能用于大多数目的,尽管在Ariadne中有一些成员支持其他操作(例如将整个内容的枚举作为原子操作出列,允许单个消费者更快地枚举) 。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM