Помимо простых случаев функций InterlockedXxx, кажется, что преобладающая модель со всеми из них состоит в том, что они реализуют свои собственные блокировки.
Ни один из ответов здесь, кажется, на самом деле не кажетсяПолучите суть разницы между «безблокировочной» петлей CAS и мьютексом или спин-блокировкой.
Важным отличием является то, что алгоритмы без блокировки гарантированно добьются прогресса самостоятельно - без помощи других потоков.С блокировкой или спин-блокировкой любой плохой поток, который не может получить блокировку, полностью во власти потока, которому принадлежит блокировка.Плохой поток, который не может получить блокировку, ничего не может сделать, кроме wait (либо из-за занятого ожидания, либо из-за ожидания ОС).
С алгоритмами без блокировки, которые зацикливаются наCAS, каждый поток гарантированно делает успехи независимо от того, что делают другие конкурирующие потоки.Каждая нить, по сути, контролирует свою судьбу.Да, он все еще может повторяться много раз, но количество циклов ограничено числом конкурирующих потоков.Это не может бесконечно зацикливаться, по большей части.(На практике возможна активная блокировка из-за, например, петли LL / SC , которая продолжает сбой из-за ложного совместного использования) - но опять-таки поток может принять меры для решения этой проблемы -это не во власти другого потока, удерживающего блокировку.
Что касается производительности, это зависит.Я видел вопиющие примеры алгоритмов без блокировок, которые полностью уступали своим аналогам блокировки даже в условиях высокой конкуренции.На компьютере с архитектурой x86-64 под управлением Debian 7 я сравнил производительность между очередью C ++ Boost.Lockfree (на основе алгоритма Майкла / Скотта) и простым старым std::queue
окружением с std::mutex
.В условиях сильного конфликта потоков версия без блокировки была почти в два раза медленнее.
Так почему это так?Что ж, производительность алгоритмов без блокировки в конечном итоге сводится к деталям реализации.Как алгоритм избегает ABA?Как добиться безопасного восстановления памяти?Существует так много вариантов ... теговые указатели, восстановление на основе эпох, RCU / состояние покоя, указатели опасности, общий сбор мусора в рамках всего процесса и т. Д. Все эти стратегии влияют на производительность, а некоторые также накладывают ограничения на то, как ваше приложение в целомможет быть разработан.В целом, по моему опыту, подходы подсчета ссылок (или подходы с теговыми указателями), как правило, работают плохо.Но альтернативы могут быть гораздо более сложными для реализации и требуют гораздо больше инфраструктуры восстановления памяти, основанной на локальном потоке хранения или обобщенной сборке мусора.