Std::mutex создает забор?

Если я заблокирую std::mutex я всегда получу забор памяти? Я не уверен, если это подразумевает или заставляет вас получить забор.

Обновить:

Нашел эту ссылку после комментариев RMF.

Многопоточное программирование и видимость памяти

2 ответа

Решение

Разблокировка мьютекса синхронизируется с блокировкой мьютекса. Я не знаю, какие опции есть у компилятора для реализации, но вы получаете тот же эффект ограждения.

Как я понимаю, это кроется в:

1.10 Многопоточные исполнения и гонки данных

Параграф 5:

Библиотека определяет ряд атомарных операций (раздел 29) и операций над мьютексами (раздел 30), которые специально определены как операции синхронизации. Эти операции играют особую роль в том, чтобы сделать назначения в одном потоке видимыми для другого. Операция синхронизации в одной или нескольких ячейках памяти является либо операцией потребления, операцией получения, операцией освобождения, либо операцией получения и освобождения. Операция синхронизации без связанной ячейки памяти представляет собой ограждение и может быть либо ограждением получения, ограждением освобождения, либо ограждением сбора и выпуска. Кроме того, существуют упрощенные атомарные операции, которые не являются операциями синхронизации, и атомарные операции чтения-изменения-записи, которые имеют специальные характеристики. [Примечание: Например, вызов, который получает мьютекс, будет выполнять операцию получения в местоположениях, составляющих мьютекс. Соответственно, вызов, который освобождает тот же мьютекс, будет выполнять операцию освобождения в тех же местах. Неформально выполнение операции освобождения A заставляет предыдущую сторону воздействовать на другие области памяти, чтобы стать видимыми для других потоков, которые позже выполняют операцию потребления или получения для A. "Расслабленные" атомарные операции не являются операциями синхронизации, даже если, как и операции синхронизации, они не могут способствовать гонкам данных. —Конечная записка]

Блокировка и разблокировка мьютексов полезна, только если мьютекс используется разными потоками. Если компилятор знает, что это не так, как если бы мьютекс представлял собой автоматическую переменную, адрес которой не взят (и не является ссылкой на нее), то для операций блокировки / разблокировки не требуется генерировать значимый код.

Операция блокировки / разблокировки мьютекса не может заменить "анонимную" (не связанную с каким-либо конкретным общим объектом синхронизации) операцию получения / освобождения, которая выполняется вызовом atomic_thread_fence; но это может показаться, что всегда с текущей наивной поддержкой потоков компилятора, которые эффективно обеспечивают atomic_thread_fence эквивалент. Но когда компиляторы начинают оптимизировать ненужные операции блокировки, они нарушают такой несоответствующий код.

Семантика потоков C/C++ (*) не позволяет заменить atomic_thread_fence в общем, это правильно: любое преобразование кода, которое удаляет вызов atomic_thread_fence только правильно в контексте.

(*) "Семантика потоков C/C++", а не "Семантика потоков языка C/C++": C и C++ основаны на одной спецификации для примитивов синхронизации, что не означает, что существует язык C/C++)

Другие вопросы по тегам