Значения std::memory_order
позволяют указывать детальные ограничения на порядок памяти, предоставляемый вашими атомарными операциями. Если вы изменяете и получаете доступ к атомарным переменным из нескольких потоков, то передача значений std::memory_order
в ваши операции позволит вам ослабить ограничения для компилятора и процессора относительно порядка, в котором выполняются операции с этими атомарными переменными становятся видимыми для других потоков, и эффекты синхронизации, которые эти операции оказывают на неатомарные данные в вашем приложении.
Порядок по умолчанию std::memory_order_seq_cst
является наиболее ограниченным и предоставляет «интуитивные» свойства, которые вы можете ожидать: если поток A сохраняет некоторые данные, а затем устанавливает атомарный флаг, используя std::memory_order_seq_cst
, то если поток B видит флаг устанавливается, тогда он может видеть, что данные записаны потоком А. Другие значения порядка памяти не обязательно обеспечивают эту гарантию, и поэтому должны использоваться очень осторожно.
Основная предпосылка: не используйте ничего, кроме std::memory_order_seq_cst
(по умолчанию), если (а) вы действительно действительно не знаете, что делаете, и не можете доказать , что расслабленное использование безопасно во всех случаях, и (b) ваш профилировщик демонстрирует, что структура данных и операции, с которыми вы собираетесь использовать смягченные заказы, являются узким местом.
Моя книга, Параллелизм C ++ в действии посвящает целую главу (45 страниц) деталям модели памяти C ++, элементарным операциям и ограничениям std::memory_order
, а также дополнительную главу (44 страницы) к использованию атомарных операций для синхронизации в структурах данных без блокировки и последствиям смягченных ограничений упорядочения.
Записи моего блога по Алгоритм Деккера и Алгоритм Петерсона для взаимного исключения демонстрируют некоторые из проблем.