Атомная операция, как правило, это код операции, который выполняет тестирование и установку. В основном это проверяет значение в памяти и, если оно равно нулю (например), увеличивает его. Пока это происходит, центральный процессор не позволит любому другому ядру получить доступ к этому местоположению, и тестирование и установка гарантированно завершатся бесперебойно. Таким образом, при вызове конечным результатом является либо значение, которое было увеличено, и ваша программа переходит в другую ветку, либо нет, и ваша программа переходит в другую ветвь.
Не у всех процессоров есть один из них, как у семейства 68000, у семейства PowerPC нет (думаю - исправления приветствуются. Я знаю, что это было правильным неудобством в системах PowerPC VME, где, как и машины предыдущего поколения на базе 68000, могли тестирование и установка на удаленных платах), уверен, что более ранние X86 тоже этого не сделали. Я уверен, что все основные современные процессоры это делают - это очень полезно.
Эффективно Test-and-Set дает вам счетный семафор, и именно для этого они и используются. Однако, имея в библиотеке лишь немного chicanery, он также может использоваться как мьютекс (который представляет собой двоичный семафор, который может быть передан только тем потоком, который его принял).
Семафоры и мьютексы AFAIK внедряются в наши дни с использованием операционных кодов Test-and-Set, доступных на процессорах. Однако на платформах, где нет операционного кода Test-and-Set, его поведение должно быть синтезировано ОС, возможно, с использованием ISR, отключением прерываний и так далее. Конечный результат ведет себя так же, но он значительно медленнее. Также на этих платформах «атомарный» должен быть синтезирован с использованием мьютексов для защиты значения.
Так что я подозреваю, что разговоры о сериализации мьютексов на уровне ядра относятся к системам, где мьютекс был реализован ядром, и атомарные операции поддерживаются процессором.
Стоит также помнить, что вызовы для получения / передачи мьютексов включают в себя принятие решениями по планированию ядра, даже если ОС затем использует операционный код test-and-set CPU для реализации части взаимного исключения мьютекса. Принимая во внимание, что вызывать тестовый и установленный код операции непосредственно из вашей программы нет; ядро понятия не имеет, что это даже случилось. Таким образом, мьютекс - это хороший способ гарантировать, что потоки с высоким приоритетом запускаются первыми, если есть конфликт, в то время как операционный код «тестируй и устанавливай», скорее всего, нет (он будет первым пришел, первым обслужен). Это будет связано с тем, что ЦП не имеет концепции приоритета потоков, это абстрактная концепция, придуманная разработчиками ОС.
Вы можете многое узнать о том, как это делается, заглянув внутрь исходного кода библиотеки Boost C ++. Такие вещи, как общие указатели, зависят от взаимного исключения, и Boost может реализовать взаимное исключение несколькими различными способами. Например, используя оп-коды в стиле test-and-set на платформах, где они есть, или используя вызовы функций библиотеки мьютекса POSIX, или если вы скажете, что в вашей программе только 1 поток, это вообще не будет беспокоить ,
Для Boost целесообразно реализовать свои собственные механизмы взаимного исключения с использованием операционных кодов, где это возможно; ему не нужно, чтобы он функционировал между процессами (просто между потоками), в то время как полноценный мьютекс POSIX является межпроцессным, избыточным для требований Boost.
С помощью Boost вы можете переопределить выбор по умолчанию, используя несколько #defines. Таким образом, вы можете ускорить однопотоковую программу, скомпилировав ее без взаимного исключения в общих указателях. Это иногда действительно полезно. Чего я не знаю, так это того, потеряно ли это в C ++ 11 и более поздних версиях, теперь, когда они освоили умные указатели и сделали их своими собственными.
EDIT
Также стоит взглянуть на futexes , которые Linux использует в качестве основы для мьютексов, семафоров и т. Д. Идея futex заключается в использовании атомарных операций для реализации основной части функциональности.полностью в пространстве пользователя, прибегая к системным вызовам, только когда это абсолютно необходимо.В результате, до тех пор, пока не слишком много споров, высокоуровневые вещи, такие как мьютекс или семафор, намного эффективнее, чем в старые добрые времена, когда они всегда приводили к системному вызову.FUTEX существуют в Linux примерно с 2003 года, поэтому мы пользуемся ими уже 15 лет.По сути, нет смысла слишком беспокоиться об эффективности мьютексов по сравнению с атомарными операциями - они не слишком далеки от того, чтобы быть тем же самым.
Что, вероятно, более важно - стремиться к чистому, опрятному исходному коду, который легко читать, и использовать вызовы библиотеки, которые помогут с этим.Использование, скажем, атомарных операций над мьютексами за счет простого исходного кода, скорее всего, не стоит.Конечно, на таких платформах, как VxWorks, которые на самом деле не имеют концепции ядра / пользовательского пространства и в первую очередь рассчитаны на быстрое переключение контекста, можно позволить себе расточительность с использованием мьютексов и семафоров для достижения простоты.,
Например, использование мьютекса для управления тем, какой поток имел доступ к определенному сетевому сокету, - это способ использования приоритетов ядра и потока для управления приоритетами различных типов сообщений, отправляемых через этот сокет.Исходный код очень прост - потоки просто принимают / передают мьютекс, используя сокет, и это все, что есть.Нет администратора очередей, нет кода принятия решений по расстановке приоритетов, ничего.Все это выполняется потоками планирования ОС в ответ на мьютекс.На VxWorks это оказывается довольно эффективным, выигрывает от ОС, решающей инверсии приоритетов, и занимает очень мало времени на разработку.В Linux, особенно с установленным набором патчей PREEMPT_RT, работающим как потоки приоритетов в реальном времени, это тоже не так уж плохо (потому что это также разрешает инверсии приоритетов, что, как я понимаю, Линусу не особо важно).В то время как в ОС, в которой нет FUTEX-ов, поддерживающих мьютексы, а также имеет дорогостоящее время переключения контекста (например, Windows), это было бы неэффективно.