Ответ 1
В общем, простая атомная выборка не предоставляется библиотеками атомных операций, потому что она редко используется; вы читаете значение, а затем делаете что-то с ним, и блокировку нужно удерживать во время этого, чтобы вы знали, что значение, которое вы прочитали, не изменилось. Таким образом, вместо атомарного чтения существует некоторый атомный тест-набор (например, gcc
__sync_fetch_and_add()
), который выполняет блокировку, а затем вы выполняете нормальные несинхронизированные чтения во время блокировки.
Исключение - это драйверы устройств, где вам может потребоваться фактически заблокировать системную шину, чтобы получить атомарность по отношению к другим устройствам на шине или при реализации блокирующих примитивов для библиотек атомных операций; они по своей сути зависят от машины, и вам придется углубиться в язык ассемблера. На процессорах x86 существуют различные атомарные инструкции, плюс префикс lock
, который может применяться к большинству операций, которые обращаются к памяти и удерживают блокировку шины в течение всего периода работы; другие платформы (SPARC, MIPS и т.д.) имеют схожие механизмы, но часто мелкие детали различаются. Вам нужно будет знать процессор, который вы программируете, и, вероятно, в этом случае нужно что-то узнать о архитектуре машинной шины. И библиотеки для этого редко имеют смысл, потому что вы не можете удерживать блокировку шины или памяти во входе/выходе функции, и даже с помощью библиотеки макросов нужно быть осторожным из-за импликации, чтобы можно было пересечь обычные операции между вызовами макросов, когда в что может нарушить блокировку. Почти всегда лучше просто закодировать весь критический раздел на ассемблере.