Enclavado y volátil


Tengo una variable que estoy usando para representar el estado. Se puede leer y escribir desde múltiples hilos.

Estoy usando Interlocked.Exchange y Interlocked.CompareExchange para cambiarlo. Sin embargo, lo estoy leyendo de varios hilos.

Sé que volatile se puede usar para asegurarse de que la variable no se almacena localmente en caché, sino que siempre lee directamente desde la memoria.

Sin embargo, si establezco la variable en volatile, genera una advertencia sobre el uso de volatile y pasa el uso de ref al Enclavado método.

Quiero asegurarme de que cada hilo está leyendo el valor más reciente de la variable y no alguna versión en caché, pero no puedo usar volatile.

Hay un Interlocked.Read pero es para tipos de 64 bits y no está disponible en el marco compacto. La documentación para ello dice que no es necesario para los tipos de 32 bits, ya que ya se realizan en una sola operación.

Hay declaraciones hechas a través de Internet que no necesita volátil si está utilizando el Métodos entrelazados para todo su acceso. Sin embargo, no puede leer una variable de 32 bits utilizando los métodos entrelazados, por lo que no hay forma de que pueda usar métodos entrelazados para todo su acceso.

¿Hay alguna manera de lograr la lectura y escritura segura del hilo de mi variable sin usar lock?

 61
Author: Stormenet, 2009-07-27

2 answers

Puede ignorar con seguridad esa advertencia cuando está utilizando funciones Interlocked.Xxx (consulte esta pregunta), porque siempre realizan operaciones volátiles. Así que una variable volatile está perfectamente bien para el estado compartido. Si desea deshacerse de la advertencia a toda costa, en realidad puede hacer una lectura entrelazada con Interlocked.CompareExchange (ref counter, 0, 0).

Editar: En realidad, necesita volatile en su variable de estado solo si va a escribir en ella directamente (es decir, no usando Interlocked.Xxx). Como jerryjvl mencionado , las lecturas de una variable actualizada con una operación entrelazada (o volátil) usarán el valor más reciente.

 32
Author: Anton Tykhyy,
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
2017-05-23 12:09:54

Las operaciones entrelazadas y volátiles no se supone que se utilicen al mismo tiempo. La razón por la que recibe una advertencia es porque (casi?) siempre indica que has malinterpretado lo que estás haciendo.

Sobre-simplificar y parafrasear:
volatile indica que cada operación de lectura necesita volver a leer desde la memoria porque puede haber otros subprocesos actualizando la variable. Cuando se aplica a un campo que puede ser leído/escrito atómicamente por la arquitectura en la que se está ejecutando, esto debería ser todo lo que necesita hacer a menos que esté utilizando long/ulong, la mayoría de los otros tipos se pueden leer/escribir atómicamente.

Cuando un campo no está marcado como volátil, puede usar Interlocked operaciones para hacer una garantía similar, porque hace que la caché se vacíe para que la actualización sea visible para todos los demás procesadores... esto tiene el beneficio de que usted pone la sobrecarga en la actualización en lugar de la lectura.

Cuál de estos dos enfoques funciona mejor depende de lo que usted está haciendo exactamente. Y esta explicación es una simplificación excesiva. Pero debe quedar claro de esto que hacer ambas cosas al mismo tiempo no tiene sentido.

 34
Author: jerryjvl,
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
2009-07-27 05:35:24