2011-12-27 12 views
5

¿Qué es mejor:
tener gran área de código de instrucción lock
o
que tienen cerraduras pequeñas en área grande ..
intercambios en esta muestra no son cambiables? .¿Cuál es la forma correcta para bloquear áreas de código

lock (padLock) 
{ 
    foreach (string ex in exchanges) 
    { 
    sub.Add(x.ID, new Subscription(ch, queue.QueueName, true)); 
......... 
} 

o

foreach (string ex in exchanges) 
{ 
    lock (padLock) 
    { 
    sub.Add(x.ID, new Subscription(ch, queue.QueueName, true)); 
    } 
..... 
+2

Depende completamente de lo que esté bloqueando. – SLaks

+0

@SLaks, creo que no entiendo completamente cuándo usar el bloqueo, entonces .. :( – 0x49D1

+1

Su ejemplo no se completa, por lo que no tiene sentido en el ámbito de la pregunta, ya que ni 'ex' ni' exchanges' no se utilizan en bucle, por lo Es difícil sugerir algo concreto – sll

Respuesta

1

El bloqueo más ancho: cuanto menos se obtenga de subprocesamiento múltiple, y viceversa Por lo tanto, el uso de bloqueos depende completamente de la lógica. Bloqueo únicas cosas y lugares que cambian y tienen que funcionar solamente por un hilo en un tiempo

Si bloquea para el uso de la colección sub - utilizar el bloqueo más pequeño, pero si ejecuta varias foreach bucles simultáneas en paralelo

1

buena práctica sería sólo para bloquear el área que desea ser ejecutado por un solo hilo en un momento dado

Si esa zona es toda bucle foreach entonces primer acercamiento está bien

pero si esa área es solo una línea como lo ha mostrado, la segunda aproximación es para el segundo enfoque

1

En En este caso en particular, la mejor opción es la primera, porque de lo contrario perderás tiempo de bloqueo/desbloqueo ya que tienes que ejecutar todo el ciclo de todos modos. Así que no hay muchas oportunidades para el paralelismo en un bucle que ejecute operaciones atómicas individualmente de todos modos.

Para obtener más consejos generales sobre los tamaños críticos sección Check este artículo: http://software.intel.com/en-us/articles/managing-lock-contention-large-and-small-critical-sections/

0

No se puede juzgar de manera efectiva que es "bien" con los fragmentos de código dado. El primer ejemplo dice que no está bien que la gente vea sub con solo una parte del contenido de los intercambios. El segundo ejemplo dice que está bien que la gente vea sub con solo una parte del contenido de los intercambios.

1

Creo que hay dos preguntas diferentes:
1. ¿Cuál sería la correcta?
2. ¿Qué le daría un mejor rendimiento?

La pregunta sobre la corrección es complicada. Depende de sus estructuras de datos y de cómo pretende que el bloqueo lo proteja. Si el objeto "sub" no es seguro para subprocesos, definitivamente necesita el bloqueo grande.

La pregunta sobre el rendimiento es más simple y menos importante (pero por alguna razón, creo que te centras más).
Muchos bloqueos pequeños pueden ser más lentos, porque simplemente hacen más trabajo. Pero si logras ejecutar una gran parte del código de bucle sin bloqueo, obtienes cierta concurrencia, por lo que sería mejor.

+0

gracias por una buena explicación. He puesto los bucles con colecciones que no son seguras para hilos en bloqueos, como he hecho con algunos fragmentos de código que contienen modificaciones de colección. Lo malo en la declaración de bloqueo grande para mí aquí fue que el bloque también contenía algunos métodos que eran de la misma clase y usaban el mismo objeto de sincronización. Así que, creo, a veces eso lleva a bloqueos (o simplemente bloqueos innecesarios) en el programa en ejecución :(Después de todo, el programa de modificaciones ahora es más receptivo. – 0x49D1

Cuestiones relacionadas