использовать volatile для обеспечения синхронизации на общем объекте. И, как вы увидите, он делает это с мьютексом; volatile используется только для предотвращения доступа к интерфейсу объекта без синхронизации.
ультате мой ответ наэтот вопросЯ начал читать про ключевое словоvolatile
и каков консенсус относительно этого. Я вижу, что есть много информации об этом, какая-то старая, которая сейчас кажется неправильной, и много новой, которая говорит, что ей почти нет места в многопоточном программировании. Следовательно, я хотел бы уточнить конкретное использование (не могу найти точный ответ здесь на SO).
Я также хочу отметить, что я понимаю требования к написанию многопоточного кода в целом и почемуvolatile
не решает проблемы. Тем не менее, я вижу код с помощьюvolatile
для управления потоками в базах кода, в которых я работаю. Кроме того, это единственный случай, когда я используюvolatile
ключевое слово, так как все другие общие ресурсы правильно синхронизированы.
Скажем, у нас есть такой класс:
class SomeWorker
{
public:
SomeWorker() : isRunning_(false) {}
void start() { isRunning_ = true; /* spawns thread and calls run */ }
void stop() { isRunning_ = false; }
private:
void run()
{
while (isRunning_)
{
// do something
}
}
volatile bool isRunning_;
};
Для простоты некоторые вещи опущены, но существенным является то, что создается объект, который делает что-то во вновь порожденном потоке, проверяя (volatile
булево, чтобы знать, должно ли это остановиться. Это логическое значение устанавливается из другого потока всякий раз, когда он хочет, чтобы работник остановился.
Насколько я понимаю, что причина для использованияvolatile
в этом конкретном случае просто избежать какой-либо оптимизации, которая бы кэшировала его в регистре для цикла. Следовательно, в результате получается бесконечный цикл. Нет необходимости правильно синхронизировать вещи, потому что рабочий поток в итоге получит новое значение?
Я хотел бы понять, считается ли это совершенно неправильным и правильно ли использовать синхронизированную переменную? Есть ли разница между компилятором / архитектурой / ядрами? Может быть, это просто небрежный подход, который стоит избегать?
Я был бы счастлив, если бы кто-то разъяснил это. Спасибо!
РЕДАКТИРОВАТЬ
Мне было бы интересно увидеть (в коде), как вы решите это.