5.3.1. Отношение синхронизируется-с
Отношение синхронизируется-с возможно только между операциями над атомарными типами. Операции над структурой данных (например, захват мьютекса) могут обеспечить это отношение, если в структуре имеются атомарные типы и определенные в ней операции выполняют необходимые атомарные операции. Однако реальным источником синхронизации всегда являются операции над атомарными типами.
Идея такова: подходящим образом помеченная атомарная операция записи W над переменной x синхронизируется-с подходящим образом помеченной атомарной операцией чтения над переменной x, которая читает значение, сохраненное либо данной операцией записи (W), либо следующей за ней атомарной операцией записи над x в том же потоке, который выполнил первоначальную операцию W, либо последовательностью атомарных операций чтения-модификации-записи над x (например, fetch_add() или compare_exchange_weak()) в любом потоке, при условии, что значение, прочитанное первым потоком в этой последовательности, является значением, записанным операцией W (см. раздел 5.3.4).
Пока оставим в стороне слова «подходящим образом помеченная», потому что по умолчанию все операции над атомарными типами помечены подходящим образом. По существу сказанное выше означает ровно то, что вы ожидаете: если поток А сохраняет значение, а поток В читает это значение, то существует отношение синхронизируется-с между сохранением в потоке А и загрузкой в потоке В — как в листинге 5.2.
Уверен, вы догадались, что нюансы как раз и скрываются за словами «подходящим образом помеченная». Модель памяти в С++ допускает применение различных ограничений на упорядочение к операциям над атомарными типами, и именно это и называется пометкой. Варианты упорядочения доступа к памяти и их связь с отношением синхронизируется-с рассматриваются в разделе 5.3.3. А пока отступим на один шаг и поговорим об отношении происходит-раньше.