Является ли bool чтение / запись атомарного в C # - PullRequest
76 голосов
/ 12 сентября 2008

Доступ к полю bool атомный в C #? В частности, нужно ли поставить замок вокруг:

class Foo
{
   private bool _bar;

   //... in some function on any thread (or many threads)
   _bar = true;

   //... same for a read
   if (_bar) { ... }
}

Ответы [ 4 ]

107 голосов
/ 12 сентября 2008

Да.

Чтение и запись следующих типов данных являются атомарными: типы bool, char, byte, sbyte, short, ushort, uint, int, float и reference.

как указано в C # Language Spec .

Редактировать: Вероятно, стоит также понять ключевое слово volatile .

44 голосов
/ 20 сентября 2008

Как указано выше, bool является атомарным, но вам все равно нужно помнить, что он также зависит от того, что вы хотите с ним делать.

if(b == false)
{
    //do something
}

не является атомарная операция, означающая, что значение b может измениться до того, как текущий поток выполнит код после оператора if.

26 голосов
/ 12 сентября 2008

bool-доступ действительно атомарный, но это еще не все.

Вам не нужно беспокоиться о чтении значения, которое «написано не полностью» - непонятно, что это может означать для bool в любом случае, - но вам, по крайней мере, нужно беспокоиться о кешах процессора если детали времени являются проблемой. Если поток № 1, работающий на ядре А, содержит ваш _bar в кэше, а _bar обновляется потоком № 2, работающим на другом ядре, поток № 1 не увидит изменения немедленно, пока вы не добавите блокировку, объявите _bar volatile или явным образом вставьте вызовы Thread.MemoryBarrier() для аннулирования кэшированного значения.

0 голосов
/ 21 мая 2013

Подход, который я использовал, и я думаю, это правильно, это

volatile bool b = false;

.. rarely signal an update with a large state change...

lock b_lock
{
  b = true;
  //other;
}

... another thread ...

if(b)
{
    lock b_lock
    {
       if(b)
       {
           //other stuff
           b = false;
       }
     }
}

цель состояла в том, чтобы избежать необходимости повторной блокировки объекта на каждой итерации, просто чтобы проверить, нужно ли нам его блокировать, чтобы предоставить большой объем информации об изменении состояния, что происходит редко. Я думаю этот подход работает. И если требуется абсолютная согласованность, я думаю, volatile подойдет для b bool.

...