Незащищенная функция get в многопоточной системе - нужна изменчивость? - PullRequest
4 голосов
/ 05 июня 2011

Я работаю над многопоточной программой, которая обеспечивает доступ к одной стороне межпроцессной системы связи. Никогда не использовавший volatile, я пытаюсь выяснить его правильное использование.
Я понимаю, что (соответствующая часть) volatile сообщает компилятору, что переменная, к которой она применяется, может быть записана вне последовательности инструкций этого потока, поэтому она должна перечитывать память каждый раз, когда она используется.

Я посмотрел некоторые учебники по volatile, но в большинстве из них либо есть простейшие примеры (например, глобальная переменная общего доступа), либо просто копируются друг друга. Затем время от времени я вижу, что кто-то, кто излагает эту изменчивость, не делает то, что, как вы думаете, делает. Кроме того, некоторые люди говорят, что если вы не пишете драйверы устройств или что-то подобное, вам не следует использовать volatile ( Требуется ли 'volatile' в этом многопоточном коде C ++? ). На данный момент мой мозг в замешательстве, и я даже не знаю, являются ли вещи, о которых я беспокоюсь, реальными проблемами. Поэтому мне интересно, есть ли какой-нибудь пример кода изменчивого использования в ООП, на который я мог бы взглянуть.

Но, в частности, моя главная проблема связана с внешним использованием функции получения. В моем коде все, что я использую, должным образом защищено, однако я предоставляю некоторые функции получения для закрытых переменных-членов, которые я не защищаю (аналогично этому вопросу Издержки мьютексов pthread? , особенно последний параграф первого ответа, или незащищенный доступ к члену в свойстве get ), потому что я не хочу связывать свой поток записи, особенно если несколько других потоков ожидают в циклах, используя функцию get.

Я обеспокоен тем, что если я не установлю переменную, доступную с помощью функции get, как volatile, то, если какая-то внешняя программа ожидает ее в цикле, то компилятор для этой внешней программы может не перечитать переменную, поэтому внешняя Программа останется в бесконечном цикле. Это действительная проблема?

Очень похожий вопрос здесь , но я не уверен, что ответ был для c ++.

Ответы [ 2 ]

3 голосов
/ 05 июня 2011

«Некоторые люди», на которых вы ссылаетесь, совершенно правы. Использование volatile гарантирует, что ячейка памяти читается или записывается каждый раз, когда вы делаете это в коде. Это не гарантирует, что значение является текущим или видимым другими потоками, которые могут работать на отдельном ядре или отдельном процессоре. Для этого вам нужен барьер памяти.

При использовании в драйвере устройства для чтения или записи внешнего оборудования это не является проблемой, поскольку оборудование будет сопоставлено с не кэшированной памятью.

3 голосов
/ 05 июня 2011

В C ++ volatile не используется для многопоточности (по крайней мере, так, как предполагалось в подобных Java 5, которая обеспечивает барьер памяти или тому подобное). В C ++ 0x есть атомарные переменные, и это ближе всего к Java 5-style volatile.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...