Es un bool lectura / escritura atómica en C#


¿Está accediendo a un campo atómico bool en C#? En particular, necesito poner un candado alrededor:

class Foo
{
   private bool _bar;

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

   //... same for a read
   if (_bar) { ... }
}
Author: dbkk, 2008-09-12

4 answers

Sí.

Las lecturas y escrituras de los siguientes tipos de datos son atómicas: bool, char, byte, sbyte, short, ushort, uint, int, float y tipos de referencia.

Como se encuentra en C# Language Spec.

Editar: Probablemente también vale la pena entender la volátil palabra clave.

 100
Author: Larsenal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-20 20:12:29

Como se indicó anteriormente, bool es atómico, pero aún debe recordar que también depende de lo que quiera hacer con él.

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

No Es un operación atómica que significa que el valor b podría cambiar antes de que el subproceso actual ejecute el código después de la instrucción if.

 39
Author: Dror Helper,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-05 10:21:46

Los accesos Bool son realmente atómicos, pero esa no es toda la historia.

No tiene que preocuparse por leer un valor que está "incompletamente escrito" - no está claro lo que eso podría significar para un bool en cualquier caso - pero tiene que preocuparse por las cachés del procesador, al menos si los detalles del tiempo son un problema. Si el subproceso # 1 que se ejecuta en el núcleo A tiene su _bar en caché, y _bar se actualiza por el subproceso # 2 que se ejecuta en otro núcleo, el subproceso #1 no verá el cambio inmediatamente a menos que agrega bloqueo, declara _bar como volatile, o inserta explícitamente llamadas a Thread.MemoryBarrier() para invalidar el valor almacenado en caché.

 25
Author: McKenzieG1,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-12 16:53:24

El enfoque que he utilizado, y creo que es correcto, es

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;
       }
     }
}

El objetivo era básicamente evitar tener que bloquear repetitivamente un objeto en cada iteración solo para comprobar si necesitábamos bloquearlo con el fin de proporcionar una gran cantidad de información de cambio de estado que ocurre rara vez. Yo creo que este enfoque funciona. Y si se requiere consistencia absoluta, yo creo volátil sería apropiado en el b bool.

 0
Author: stux,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-05-21 07:52:13