Veo que para usar objetos que no son seguros para subprocesos envolvemos el código con un bloqueo como este:
private static readonly Object obj = new Object();
lock (obj)
{
// thread unsafe code
}
Entonces, ¿qué sucede cuando varios subprocesos acceden al mismo código (supongamos que se ejecuta en una aplicación web ASP.NET). ¿Están en cola? Si es así, ¿cuánto tiempo esperarán?
¿Cuál es el impacto en el rendimiento debido al uso de bloqueos?
Respuestas:
La
lock
declaración es traducida por C # 3.0 a la siguiente:En C # 4.0 esto ha cambiado y ahora se genera de la siguiente manera:
Puedes encontrar más información sobre lo que
Monitor.Enter
hace aquí . Para citar MSDN:El
Monitor.Enter
método esperará infinitamente; No se agotará el tiempo.fuente
obj
sin que todo el sistema quede en punto muerto.lock
declaración y el monitor: para que pueda realizar una operación en un hilo sin tener que preocuparse de que otro hilo lo arruine.Es más simple de lo que piensas.
Según Microsoft : la
lock
palabra clave asegura que un hilo no entre en una sección crítica de código mientras otro hilo está en la sección crítica. Si otro hilo intenta ingresar un código bloqueado, esperará, bloqueará, hasta que se libere el objeto.La
lock
palabra clave llamaEnter
al comienzo del bloque yExit
al final del bloque.lock
La palabra clave realmente maneja laMonitor
clase en el back-end.Por ejemplo:
En el código anterior, primero el hilo entra en una sección crítica, y luego se bloqueará
obj
. Cuando otro subproceso intenta ingresar, también intentará bloquearobj
, que ya está bloqueado por el primer subproceso. El segundo hilo tendrá que esperar a que se libere el primer hiloobj
. Cuando sale el primer hilo, otro se bloquearáobj
y entrará en la sección crítica.fuente
No, no están en cola, están durmiendo.
Una declaración de bloqueo del formulario
donde x es una expresión de un tipo de referencia, es precisamente equivalente a
Solo necesita saber que se están esperando el uno al otro, y solo ingresará un hilo para bloquear el bloqueo, los otros esperarán ...
Monitor está escrito completamente en .net, por lo que es lo suficientemente rápido, también mire la clase Monitor con reflector para obtener más detalles
fuente
lock
declaración cambió ligeramente en C # 4: blogs.msdn.com/b/ericlippert/archive/2009/03/06/…Los bloqueos bloquearán que otros hilos ejecuten el código contenido en el bloque de bloqueo. Los hilos tendrán que esperar hasta que el hilo dentro del bloque de bloqueo se haya completado y se libere el bloqueo. Esto tiene un impacto negativo en el rendimiento en un entorno multiproceso. Si necesita hacer esto, debe asegurarse de que el código dentro del bloque de bloqueo pueda procesarse muy rápidamente. Debe intentar evitar actividades costosas como acceder a una base de datos, etc.
fuente
El impacto en el rendimiento depende de la forma en que se bloquea. Puede encontrar una buena lista de optimizaciones aquí: http://www.thinkingparallel.com/2007/07/31/10-ways-to-reduce-lock-contention-in-threaded-programs/
Básicamente, debe tratar de bloquear lo menos posible, ya que pone su código de espera para dormir. Si tiene algunos cálculos pesados o un código de larga duración (por ejemplo, carga de archivos) en un bloqueo, se produce una gran pérdida de rendimiento.
fuente
do { oldValue = thing; newValue = updated(oldValue); } while (CompareExchange(ref thing, newValue, oldValue) != oldValue
]. El mayor peligro es que si los requisitos evolucionan más allá de lo que pueden manejarse tales técnicas, puede ser difícil adaptar el código para manejar eso.La parte dentro de la declaración de bloqueo solo puede ejecutarse mediante un subproceso, por lo que todos los demás subprocesos esperarán indefinidamente a que finalice el subproceso que mantiene el bloqueo. Esto puede resultar en un llamado punto muerto.
fuente
La
lock
declaración se traduce en llamadas a los métodosEnter
yExit
deMonitor
.La
lock
declaración esperará indefinidamente a que se libere el objeto de bloqueo.fuente
el bloqueo está realmente oculto Clase de monitor .
fuente