Реализация очереди без блокировки (для компонента Logger) - PullRequest
2 голосов
/ 05 января 2012

Я разрабатываю новый улучшенный компонент Logger (.NET 3.5, C #).

Я хотел бы использовать реализацию без блокировки.

События журналирования будут отправляться из (потенциально) нескольких потоков, хотя только один поток будет выполнять фактический вывод на файл / другой носитель.

По сути, все авторы * помещают * свои данные в некоторую очередь для извлечения другим процессом (LogFileWriter).

Может ли это быть достигнуто без блокировки? я не мог найти прямую ссылку на эту конкретную проблему в сети.

Ответы [ 3 ]

13 голосов
/ 05 января 2012

Если вы обнаружите, что использование блокировки в этом случае слишком медленное, у вас гораздо большая проблема.Блокировка, если она не оспаривается, занимает в моей системе около 75 наносекунд (2,0 ГГц Core 2 Quad).Конечно, когда это утверждается, это займет немного больше времени.Но поскольку блокировка просто защищает вызов к Enqueue или Dequeue, маловероятно, что общее время записи журнала будет намного больше, чем 75 наносекунд.

Если блокировка проблема - то есть, если вы обнаружите, что ваши потоки выстраиваются в очередь за этой блокировкой и вызывают заметное замедление в вашем приложении - тогда маловероятно, что создание очереди без блокировок может сильно помочь.Зачем?Потому что, если вы действительно так много записываете в журнал, ваша очередь блокировки без блокировки будет заполняться так быстро, что вы будете ограничены скоростью подсистемы ввода / вывода.

У меня естьмногопоточное приложение, которое записывает порядка 200 записей в секунду в Queue<string>, защищенное простой блокировкой.Я никогда не замечал сколько-нибудь значительных конфликтов блокировок, и обработка ничуть не замедлилась.Эти 75 нс затмеваются временем, необходимым для всего остального.

5 голосов
/ 05 января 2012

Эта реализация очереди без блокировки может быть полезна, когда очередь - это структура данных, которую вы будете использовать для постановки в очередь элементов, подлежащих снятию в очередь и выписыванию регистратором.

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

Вы также можете посмотреть ConcurrentQueue в .Net 4

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

0 голосов
/ 05 января 2012

Существует довольно много различных реализаций очередей без блокировки.

Моя собственная на http://hackcraft.github.com/Ariadne/ использует простой подход и является открытым исходным кодом, так что вы можете адаптировать его при необходимости.

ConcurrerntQueue также не блокируется и, вероятно, отлично подойдет для большинства целей, хотя в Ариадне есть несколько членов, поддерживающих другие операции (например, исключение перечисления всего содержимого в качестве атомарной операции, которая позволяетболее быстрое перечисление одним потребителем).

...