Если Вам будет интересно более подробно о том, как кластер Google работает, я предложу эту реализацию с открытым исходным кодом их HDFS.
Это основано Mapreduce Google.
Вы не синхронизируете доступ к элементу заголовка списка. Это плохо по крайней мере на двух уровнях:
присвоение значений заголовку списка может быть не таким атомарным, как вы думаете. Это означает, что несинхронизированная операция чтения потенциально может получить поврежденное значение.
Другая, более вероятная проблема заключается в том, что если ваш блок имеет несколько ядер, каждое из них может иметь в кэше процессора свою собственную копию значения. Чтобы они синхронизировали значения, вам нужен барьер памяти
As you discovered, lock free programming is very difficult to get right.
Windows already has support for lock-free singly linked lists,http://msdn.microsoft.com/en-us/library/ms684121(VS.85).aspx, you should try using that rather than roll your own.
The most obvious error is the name you've given it. Regardless of the fact that you've implemented it as a linked list, what you've implemented is a stack.
Consider what would happen in the following sequence of events when there are two items, A and B, in the list (stack really) like head -> A -> B
, count
is 2:
pop()
call but gets preempted right before _InterlockedCompareExchange64()
head -> A -> D
. Note that the count
is back to 2
_InterlockedCompareExchange64()
). Now head
points to B, which was deallocated (bad) and D is lost (bad).
Это классическая проблема ABA . Вы должны использовать второе слово в качестве номера поколения вместо количества элементов, то есть никогда не уменьшайте его.
В списке рассылки ведется обсуждение экспериментальной библиотеки boost :: lockfree .
Также обратите внимание на очередь Херба Саттера без блокировок - это другой подход, при котором фиктивный узел не дает производителю и потребителю наступать друг на друга.