C++, volatile и блокируемые разделяемые объекты

У меня есть несколько вопросов про volatile в C++:

  1. Существует мнение, что разделяемые объекты (аля, связный список, все методы которого защищены внутренним мьютексом) не нужно делать volatile при использовании из разных потоков. Вопрос - почему? Если volatile нужен для объяснения компилятору того факта, что значение может измениться неожиданным образом и его не нужно оптимизировать, тогда почему связный список, который синхронизирует доступ к себе сам, нормально работает при использовании из разных потоков и без спецификатора volatile?
  2. Какова семантика метода, который помечен спецификатором volatile?
  3. Когда вообще нужно применять спецификатор volatile? Пример с циклом, который управляется флагом, который меняется из другого потока, слишком упрощен и при рассмотрении реальных сценариев C++ ясности не дает никакой.

Ответы (1 шт):

Автор решения: KoVadim

Существует мнение, что разделяемые объекты (аля, связный список, все методы которого защищены внутренним мьютексом) не нужно делать 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 может быть связанна с каким то внешним устройством и запись в эту переменную будет делать запись в какой то порт ввода-вывода. И оптимизация будет только мешать.

→ Ссылка