В Интернете можно найти много споров об использовании ключевого слова volatile
в параллельном программировании, иногда с противоречивой аргументацией.
Одним из наиболее заслуживающих доверия обсуждений этой темы является эта статья Арка Робисона .В качестве примера он использует задачу передачи значения из одного потока в другой:
Поток 1. вычисляет матричный продукт и передает его в Поток 2, который делает с ним что-то другое.Матрица является переменной M
, а флаг является volatile
указателем R
.
- . Поток 1 умножает, вычисляет матричное произведение M и атомарно устанавливает R для указания на M.
- Поток 2 ожидает, пока R! = NULL, а затем использует M в качестве фактора для вычисления другого матричного произведения.
Другими словами, M - это сообщение, а R - флаг готовности.
Автор утверждает, что хотя объявление R в качестве энергозависимого решит проблему с распространением изменения из потока 1 в поток 2, оно не дает никаких гарантий относительно того, каким будет значение M, когда этослучается.И назначения на R
и M
могут быть переупорядочены.Поэтому нам нужно сделать оба параметра M
и R
volatile или использовать некоторый механизм синхронизации в некоторой библиотеке, такой как pthreads.
У меня вопрос, как сделать следующее в C
1)Как разделить один флаг между двумя потоками - Как атомарно назначить ему, убедитесь, что другой поток увидит изменение и проверит изменения в другом потоке.Законно ли использование volatile в этом случае?Или какая-нибудь библиотека может предложить концептуально лучший или более быстрый способ, возможно, с использованием барьеров памяти?
2) Как правильно сделать пример Робисона, как отправить матрицу M из одного потока в другой и сделать это безопасно(и предпочтительно переносимо с нитями)