Являются ли примитивные типы данных в c # атомарными (потокобезопасными)? - PullRequest
9 голосов
/ 12 марта 2010

Например, нужно ли блокировать значение bool при многопоточности?

Ответы [ 4 ]

17 голосов
/ 12 марта 2010

Нет такого понятия, как атомный тип . Только операции могут быть атомарными.

Чтение и запись типа данных, который вписывается в одно слово (int на 32-разрядном процессоре, long на 64-разрядном процессоре), технически "атомарен", но дрожание и / или процессор могут решите изменить порядок команд и, таким образом, создать непредвиденные условия гонки, поэтому вам нужно либо сериализовать доступ с lock, использовать класс Interlocked для записи (и в некоторых случаях чтения), либо объявить переменную volatile.

Краткий ответ: если два разных потока могут обращаться к одному и тому же полю / переменной и по крайней мере один из них будет писать, вам нужно использовать какой-то тип блокировки. Для примитивных типов это, как правило, класс Interlocked.

2 голосов
/ 12 марта 2010

Вроде. Об этом есть отличная ветка , но короткая версия такова, что хотя данное чтение или запись может быть атомарным, это почти никогда не то, что вы делаете. Например, если вы хотите увеличить целое число, вам необходимо: 1) прочитать значение, 2) добавить единицу к значению и 3) сохранить значение обратно. Любая из этих операций может быть прервана.

Вот почему такие классы, как "Interlocked".

2 голосов
/ 12 марта 2010

Аналогичный вопрос здесь

Для окончательного ответа перейдите к спекуляция :)

Раздел I, раздел 12.6.6 CLI Спецификация гласит: «Соответствующий CLI должен гарантировать доступ для чтения и записи правильно выровненные места памяти не больше размера родного слова атомарный, когда все записи обращаются к местоположение одного размера. "

Так что это подтверждает, что s_Initialized никогда не будет нестабильным, и это читать и пишет в примитивные типы атомарный.

Блокировка создает барьер памяти чтобы предотвратить процессор переупорядочение чтения и записи. Замок создает единственный необходимый барьер в этот пример.

Джон.

По сути, у вас не возникнет проблема "сбоя", если не заблокировать бул. То, что у вас может быть, - это состояние гонки, для порядка, в котором bool обновляется или читается. Если вы хотите гарантировать, что bool записывается / читается в определенном порядке, вам следует использовать какой-либо механизм блокировки.

0 голосов
/ 12 марта 2010

Типы статических примитивов безопасны для потоков, поэтому вам не нужно блокировать эти типизированные переменные. Однако любая переменная экземпляра примитивного типа не гарантируется. Смотрите здесь: Являются ли примитивные типы похожими на bool threadsafe?

Класс MSDN PrimitiveType

А вот еще одна полезная ссылка, которая также может быть интересна, и я считаю решение весьма убедительным: SO Вопрос: Как узнать, является ли метод C # поточно-ориентированным?

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