2010-01-05 10 views
12

En .NET es la palabra clave lock azúcar sintáctico alrededor Monitor.Enter y Monitor.Exit, por lo que se podría decir que este códigoAl utilizar el bloqueo contra MemoryBarrier en .NET

lock(locker) 
{ 
    // Do something 
} 

es lo mismo que

Monitor.Enter(locker); 
try 
{ 
    // Do Something 
} 
finally 
{ 
    Monitor.Exit(locker); 
} 

Sin embargo, el .NET framework también incluye la clase MemoryBarrier que funciona de manera similar

Thread.MemoryBarrier(); 
//Do something 
Thread.MemoryBarrier(); 

Estoy confundido como cuando quisiera usar Thread.MemoryBarrier sobre la versión lock/Monitor? Estoy aún más confundido por a Threading Tutorial que indica que funcionan lo mismo.

Por lo que puedo ver, la diferencia visible no necesita un objeto de bloqueo, lo que supongo que al usar Monitor podría hacer algo entre subprocesos donde MemoryBarrier está en una sola cadena.

Mi instinto me dice que otra diferencia clave es MemoryBarrier es solo para variables y no para métodos.

Por último, esto no está relacionado con la pregunta existente When to use ‘volatile’ or ‘Thread.MemoryBarrier()’ in threadsafe locking code? (C#), ya que se está centrando en la palabra clave volatile que entiendo su uso.

Respuesta

22

En mi opinión, debería casi nunca utilizar Thread.MemoryBarrier. Esto se utiliza para código sin bloqueo - asegurándose de que los cambios realizados en un hilo sean visibles para otro sin incurrir en el costo de un bloqueo. No hace no sincronización del hilo de control, a diferencia de lock. No veo en qué parte del tutorial de Joe dice que MemoryBarrier "funciona igual" que lock. ¿Podría explicar de dónde exactamente está obteniendo esa impresión?

En mi opinión, el código de bloqueo de bajo nivel es demasiado difícil para casi cualquier persona que no sea un desarrollador cuyo dominio principal sea la concurrencia. Si quiero escribir algún código sin candado, usaré los bloques de construcción de mayor nivel construidos por esos desarrolladores (como las Extensiones Paralelas en .NET 4.0) en lugar de intentar hacer los míos.

A modo de ejemplo, recientemente he tenido mis ojos abiertos al significado preciso de volatile, que no es "siempre se lee de la memoria principal, siempre escribir directamente en la memoria principal". (Mi propio tutorial de subprocesos todavía tiene esa explicación en este momento, algo que necesito solucionar en algún momento). It's far more subtle than that. Esto significa que algunos de mis usos anteriores de volatile pueden ser incorrectos.

+0

En el tutorial de Joe (en la página que enlazo) buscar 'Barreras de memoria y bloqueo' hay un breve párrafo que dice que son equivalentes "si ignoramos la garantía de exclusión mutua de un candado". –

+1

Sin embargo, ignorar la exclusión mutua hace que la comparación no tenga sentido ya que es un componente integral de los bloqueos – Grizzly

+1

@Grizzly: La comparación no es inútil; es útil en términos de * vallas *. Pero eso no es lo mismo que decir que las dos cosas "funcionan igual", porque la garantía de exclusión mutua es el principal punto de bloqueo. –

Cuestiones relacionadas