2010-06-11 2 views
8

Я подумал: возможно ли иметь блокировку очереди, когда более одного темы читают или пишут? Я видел реализацию с заблокированной очередью, которая работала с одним прочитанным и одним потоком записи, но не более одного. Является ли это возможным? Я не думаю, что это так. Может ли кто-нибудь это доказать?Есть ли такая вещь, как блокированная очередь для нескольких потоков чтения или записи?

ответ

13

Есть несколько алгоритмов доступны, я в конечном итоге реализации An Optimistic Approach to Lock-Free FIFO Queues, что позволяет избежать проблем ABA через указатель пометки (нуждается в CMPXCHG8B инструкции по x86), и он прекрасно работает в приложении производства (написанном в Delphi). (Another version, with Java code)

Тем не менее, чтобы быть на самом деле, действительно беззамочные, вы также должны стопорное свободного распределения памяти - см Scalable Lock-Free Dynamic Memory Allocation (реализованный в Concurrent Building Block) или NBMalloc (но до сих пор я не получил использовать один из эти).

Вы также можете посмотреть ответы на optimistic lock-free FIFO queues impl?

+0

Я не понимал CAS, пока не прочитал инструкцию CMPXCHG. Инструкция CMPXCHG выглядит круто, поэтому я беру ее, если ее успех установит флаг Z? Теперь после минут путаницы с CAS до чтения CMPXCHG CAS выглядит как CAS (dst, oldValue, newVal); где dst - адрес, а два других - значения? если true, если dst была старой стоимостью и теперь заменена на newValue? (Я знаю, что много говорила, но думаю, что я прав, кажется, очень прав). – 2010-06-11 19:05:02

+0

Знаете ли вы, есть ли существующие версии C++ 11 вашей статьи? Похоже, что это требует некоторой осторожности для реализации, и, хотя я действительно могу это использовать, я собираюсь пойти на реализацию блокировки, которую легче понять и проанализировать. – Omnifarious

+0

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

0

Вам не нужна блокировка, а атомный способ удаления вещей из очереди. Это также возможно без блокировки и с атомной инструкцией test-and-set.

+0

Является ли это одной команды процессора? – 2010-06-11 09:37:11

+0

Инструкция по сборке CMPXCHG – Sjoerd

2

реализация в Java из очереди беззамочной позволяет одновременно читает и пишет. Эта работа выполняется с помощью операции сравнения и установки (которая является одной инструкцией CPU).

В методе ConcurrentLinkedQueue используется метод, при котором потоки помогают друг другу читать (или опросить) объекты из очереди. Поскольку он связан, глава очереди может принимать записи, в то время как хвост очереди может принимать чтения (при достаточном количестве места). Все это можно сделать параллельно и полностью безопасно для потоков.

0

С .NET 4.0 существует ConcurrentQueue Class.

Образец

https://dotnetfiddle.net/ehLZCm

public static void Main() 
{ 
    PopulateQueueParallel(new ConcurrentQueue<string>(), 500); 
} 

static void PopulateQueueParallel(ConcurrentQueue<string> queue, int queueSize) 
{ 
    Parallel.For(0, queueSize, (i) => queue.Enqueue(string.Format("my message {0}", i))); 
    Parallel.For(0, queueSize, 
     (i) => 
     { 
      string message; 
      bool success = queue.TryDequeue(out message); 
      if (!success) 
       throw new Exception("Error!"); 

      Console.WriteLine(message); 
     }); 
}