Разъяснения о полных барьерах памяти, связанных с мьютексами pthread
Я слышал, что при работе с мьютексами необходимые барьеры памяти обрабатываются самим API-интерфейсом pthread. Я хотел бы получить более подробную информацию по этому вопросу.
- Верны ли эти утверждения, по крайней мере, для наиболее распространенных архитектур вокруг?
- Распознает ли компилятор этот неявный барьер и избегает переупорядочения операций / чтения из локальных регистров при генерации кода?
- Когда применяется барьер памяти: после успешного получения мьютекса и после его освобождения?
1 ответ
В спецификации POSIX перечислены функции, которые должны "синхронизировать память по отношению к другим потокам", в том числе такие функции, как pthread_mutex_lock()
а также pthread_mutex_unlock()
,
В Приложении А.4.11 прописано, что функции, "синхронизирующие память":
... должны были бы распознаваться передовыми системами компиляции, чтобы операции памяти и вызовы этих функций не переупорядочивались при оптимизации; а также
... может потребоваться добавить инструкции по синхронизации памяти, в зависимости от конкретной машины.
Никогда не указывается явно, какие инструкции синхронизации памяти подразумеваются - неявная спецификация состоит в том, что если вы используете пару "инструкций синхронизации", чтобы гарантировать, что чтение в одном потоке должно произойти после записи в другом, то ваша программа будет действуй правильно. Это включает как компилятор, так и эффекты архитектурного переупорядочения.