Joe Albahari имеет great series на многопоточности, который должен быть прочитан и должен быть известен наизусть для всех, кто выполняет многопоточность C#.Является ли слово «volatile» все еще сломанным в C#?
В части 4, однако он упоминает о проблемах с летучим:
Обратите внимание, что применение летучего не препятствует записи с последующим чтением от быть обменены, и это может создать задачки. Joe Duffy хорошо иллюстрирует проблему в следующем примере: если Test1 и Test2 работают одновременно на разных потоках, возможно, что a и b оба получат значение 0 (несмотря на использование volatile на как x, так и у)
Вслед за примечанием, что документация MSDN неверно:
в документации MSDN говорится, что использование летучего ключевого слова гарантирует , что наибольшая ценность уточненного присутствует в поле всегда. Это неверно, так как, как мы видели, запись с последующим считыванием может быть изменена на .
Я проверил MSDN documentation, который был последний раз изменялся в 2015 году, но до сих пор списки:
Летучие ключевое слово указывает на то, что поле может быть изменено несколько потоков, которые выполняются одновременно , Поля, которые являются объявленными volatile, не подпадают под оптимизацию компилятора, которые предполагают доступ одним потоком. Это гарантирует, что самое актуальное значение присутствует в поле в любое время.
Сейчас я до сих пор избежать волатильным в пользу более многословным, чтобы предотвратить темы с использованием устаревших данных:
private int foo;
private object fooLock = new object();
public int Foo {
get { lock(fooLock) return foo; }
set { lock(fooLock) foo = value; }
}
как части о многопоточности были написаны в 2011 году, является аргументом по-прежнему актуальны сегодня? Должен ли волатильность все же избегать любой ценой в пользу блокировок или полных ограждений памяти, чтобы предотвратить очень сложное создание ошибок, которые, как уже упоминалось, даже зависят от поставщика процессора, на котором он работает?
В чем смысл внешнего выражения 'return' и присваивания' lock' в вашем примере? – Yarik
Это по-прежнему вводит в заблуждение. Volatile обеспечивает семантику памяти получения/выпуска, которой достаточно для эффективного выполнения многих алгоритмов. Да, это сложно использовать, но это не делает его сломанным (решение C++ явно превосходит, но у них было преимущество видеть проблемы с volatile в java) (И любой, кто считает, что барьеры памяти легче, чем изменчивые, просто не хватает опыт работы с архитектурами, отличными от x86.Попытайтесь использовать барьеры памяти в архитектуре без многократной атомарности и посмотреть, как далеко вы достигнете) – Voo
(Описание msdn, по общему признанию, заметно хуже. Очевидно, кто бы ни писал этот фрагмент, он вообще не понимает изменчивости, и надежда не может быть разрешена только написать одну строку параллельного кода) – Voo