Java изменчива в C? - PullRequest
       16

Java изменчива в C?

4 голосов
/ 10 февраля 2012

Мне известно об использовании volatile в Java.То есть (основываясь на статье Википедии ):

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

Я также знаю, что существует ключевое слово volatileв C, но в совершенно ином контексте, главным образом для использования в отображаемых в память вводах / выводах.

Так что мне было интересно, есть ли какая-нибудь конструкция, подобная Java volatile в C?Что помешает чтению кэшированных значений переменной?

Если она не существует в C, возможно, есть библиотека с такой конструкцией, как pthread?

Ответы [ 2 ]

5 голосов
/ 10 февраля 2012

volatile в C - это в основном анахронизм, который был предназначен для совершенно другого сценария и НЕ полезен для многопоточного программирования. По тем или иным причинам даже самый новый стандарт c ++ не мог придать ему большего значения, но вместо этого ему пришлось изобрести новое ключевое слово.

Имейте в виду, это означает, что volatile, как определено стандартом C, бесполезно, компиляторы могут дать вам дополнительные гарантии (я знаю, что MS VC дает, и я думаю, что это дает в основном те же гарантии, что и volatile в Java), но это означает программа заблокирована для этого одного компилятора. Большинство компиляторов также имеют некоторые особенности для вставки барьеров памяти, которые немного более явные, но опять же не переносимые сами по себе.

На практике вам, вероятно, лучше всего использовать какую-нибудь высокоуровневую библиотеку потоков, которая предлагает правильные инструменты для работы. Например. POSIX дает вам низкий уровень барьеров памяти afaik.

На сайте c ++ лучше с 0x11 - стандарт предлагает std::atomic_thread_fence и атомарные переменные. Обратите внимание, что модель памяти c ++ 0x11 NOT идентична модели Java, поэтому вам следует быть осторожным при переносе.

3 голосов
/ 10 февраля 2012

Поведение volatile не обязательно отличается; это платформа и контекст, который отличается. Вы конкретно упомянули устройства с отображенной памятью в своем вопросе. Если у вас есть устройство с отображенной памятью, например какое-то оборудование, которое может перевернуть регистр, который представлен переменной в вашем коде, тогда, очевидно, вам нужен способ указать это. Если вы этого не сделаете, то компилятор всегда будет работать при условии, что единственная система, которая может изменить ваш код, - это ваша программа и может оптимизировать ее.

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

Java "кэши" в основном одинаковы. Кажется, что ваше разъединение происходит из-за того, что вы не устанавливаете ментальный мост между компилируемым кодом C и Java, являющимся JIT-компилируемым байтовым кодом, работающим внутри виртуальной машины. Java наследует свое поведение volatile от C, но последствия этого поведения радикально отличаются из-за контекста времени выполнения.

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