2009-02-05 10 views
5

Supongamos que tengo una variable "counter", y hay varios hilos con el acceso y estableciendo el valor de "contador" Mediante el uso Endentado, es decir:¿Interlocked proporciona visibilidad en todos los hilos?

int value = Interlocked.Increment(ref counter); 

y

int value = Interlocked.Decrement(ref counter); 

¿Puedo asumir que , el cambio realizado por Interlocked será visible en todos los hilos?

Si no, ¿qué debo hacer para que todos los hilos sincronicen la variable?

EDITAR: alguien me sugirió usar volátil. Pero cuando configuro el "contador" como volátil, hay una advertencia del compilador "la referencia al campo volátil no se tratará como volátil".

Cuando leí la ayuda en línea, decía: "Normalmente, un campo volátil no debería pasarse utilizando un parámetro ref o out".

+0

Sí, el incremento/disminución entrelazados (en x86 e IA-64) automáticamente otorga visibilidad a todos los hilos, ya que tiene una barrera de memoria implícita. Volátil no es necesario (aunque no es ilegal). – minjang

Respuesta

7

InterlockedIncrement/decremento en CPUs x86 (de x86 bloqueo add/DEC) están creando automáticamente barrera memoria que da visibilidad a todas las roscas (es decir, todas las discusiones puede ver su actualización como en orden, como la coherencia de memoria secuencial). La barrera de memoria hace que todas las cargas/almacenes de memoria pendientes se completen. volatile no está relacionado con esta pregunta, aunque C# y Java (y algunos compiladores C/C++) imponen volatile para hacer que la barrera de memoria. Pero, la operación interbloqueada ya tiene barrera de memoria por CPU.

Por favor, eche un vistazo a my another answer en stackoverflow.

Tenga en cuenta que supongo que C# 'InterlockedIncrement/Decrement es un mapeo intrínseco a x86's lock add/dec.

0

El enclavamiento asegura que solo 1 hilo a la vez puede actualizar el valor. Para asegurarse de que otros subprocesos puedan leer el valor correcto (y no un valor en caché) márquelo como volátil.

public vollatile int Counter;

+0

cuando marqué como volátil, hay una advertencia de compilación. "la referencia al campo volátil no se tratará como volátil". –

+0

ignore esa advertencia para este caso: http://stackoverflow.com/questions/425132/a-reference-to-a-volatile-field-will-not-be-treated-as-volatile-implications –

+1

Aparentemente no lo hace Necesito Volátil si está usando Enclavamiento, pero si está modificando sin usar Enclavamiento, entonces lo hace. –

0

En realidad, no lo son. Si quiere modificar de manera segura counter, está haciendo lo correcto. Pero si quiere leer counter directamente, debe declararlo como volatile. De lo contrario, el compilador no tiene motivos para creer que counter cambiará porque las operaciones Interlocked están en un código que podría no verse.

+0

¿Por qué el voto a favor? Esto es correcto. – MSN

3

¿Puedo suponer que el cambio realizado por Enclavamiento será visible en todos los hilos?

Esto depende de cómo se lea el valor. Si "solo" lo lees, entonces no, esto no siempre será visible en otros hilos a menos que lo marques como volátil. Eso causa una advertencia molesta sin embargo.

Como alternativa (y muy preferida como IMO), léala usando otra instrucción Interlocked. Esto siempre verá el valor actualizado de todas las discusiones:

int readvalue = Interlocked.CompareExchange(ref counter, 0, 0); 

que devuelve el valor leído, y si era 0 permutas de TI con 0.

motivación: la advertencia insinúa que algo no está bien; combinar las dos técnicas (volátil & interbloqueado) no fue la forma prevista de hacerlo.

Actualización: parece que otro enfoque para las lecturas confiables de 32 bits sin usar "volátil" es mediante el uso de Thread.VolatileRead como se sugiere en this answer. También hay alguna evidencia de que estoy completamente equivocado sobre el uso de Interlocked para lecturas de 32 bits, por ejemplo this Connect issue, aunque me pregunto si la distinción es un poco pedante por naturaleza.

Lo que realmente quiero decir es: no use esta respuesta como su única fuente; Tengo mis dudas sobre esto.

Cuestiones relacionadas