C++, volatile и блокируемые разделяемые объекты
У меня есть несколько вопросов про volatile в C++:
- Существует мнение, что разделяемые объекты (аля, связный список, все методы которого защищены внутренним мьютексом) не нужно делать
volatileпри использовании из разных потоков. Вопрос - почему? Еслиvolatileнужен для объяснения компилятору того факта, что значение может измениться неожиданным образом и его не нужно оптимизировать, тогда почему связный список, который синхронизирует доступ к себе сам, нормально работает при использовании из разных потоков и без спецификатораvolatile? - Какова семантика метода, который помечен спецификатором
volatile? - Когда вообще нужно применять спецификатор
volatile? Пример с циклом, который управляется флагом, который меняется из другого потока, слишком упрощен и при рассмотрении реальных сценариевC++ясности не дает никакой.
Ответы (1 шт):
Существует мнение, что разделяемые объекты (аля, связный список, все методы которого защищены внутренним мьютексом) не нужно делать volatile при использовании из разных потоков. Вопрос - почему?
Потому что сам примитив синхронизации (мютекс) является "барьером". Тема обширная и в одном ответе не раскрыть. Но можно начать читать здесь http://scrutator.me/post/2012/04/04/parallel-world-p1.aspx и Энтони Уильям - Книга "Параллельное программирование на C++ в действии. Практика разработки многопоточных программ"
Но если говорить простым языком, то если один потом модифицировал разные переменные и отпустил мютекс, а другой захватил этот же мютекс и пытается читать эти же переменные, то их состояние будет "ожидаемым". А без захвата мютекса - не факт.
Какова семантика метода, который помечен спецификатором volatile?
ну нет в с++ методов. Есть функция член класса, ну или просто функция. А семантика такая же как и const - Ваш this будет volatile.
Когда вообще нужно применять спецификатор volatile? Пример с циклом, который управляется флагом, который меняется из другого потока, слишком упрощен и при рассмотрении реальных сценариев C++ ясности не дает никакой.
volatile следует применять при разработке драйверов и микроконтроллеров. Основаная суть volatile раскрывает такой пример
volatile int a;
a = 1;
a = 2;
без volatile компилятор просто выбросит первое присваивание. Оно бессмысленно. А с volatile запись будет произведена дважды. Зачем? а переменная a может быть связанна с каким то внешним устройством и запись в эту переменную будет делать запись в какой то порт ввода-вывода. И оптимизация будет только мешать.