Reentrantes lockings en C #

¿El siguiente código dará como resultado un punto muerto usando C # en .NET?

class MyClass { private object lockObj = new object(); public void Foo() { lock(lockObj) { Bar(); } } public void Bar() { lock(lockObj) { // Do something } } } 

No, no mientras estés bloqueando el mismo objeto. El código recursivo efectivamente ya tiene el locking y así puede continuar sin obstáculos.

lock(object) {...} es una abreviatura para usar la clase Monitor . Como señala Marc , Monitor permite la reentrada , por lo que los bashs repetidos de bloquear un objeto en el que el hilo actual ya tiene un locking funcionarán perfectamente.

Si comienzas a bloquear objetos diferentes , entonces es cuando debes tener cuidado. Presta especial atención a:

  • Siempre adquiera cerraduras en un número determinado de objetos en la misma secuencia.
  • Siempre suelte lockings en la secuencia inversa a cómo los adquiere.

Si incumples cualquiera de estas reglas, es casi seguro que tendrás problemas de interlocking en algún momento .

Aquí hay una buena página web que describe la sincronización de subprocesos en .NET: http://dotnetdebug.net/2005/07/20/monitor-class-avoiding-deadlocks/

Además, bloquee la menor cantidad posible de objetos a la vez. Considere la posibilidad de aplicar lockings de grano grueso cuando sea posible. La idea es que si puede escribir su código de modo que haya un gráfico de objetos y pueda adquirir lockings en la raíz de ese gráfico de objetos, hágalo. Esto significa que tiene un locking en ese objeto raíz y, por lo tanto, no tiene que preocuparse demasiado por la secuencia en la que adquiere / suelta lockings.

(Una nota adicional, su ejemplo no es técnicamente recursivo. Para que sea recursivo, Bar() debería llamarse a sí mismo, normalmente como parte de una iteración).

Bueno, Monitor permite la reentrada, por lo que no puedes estancarte … así que no: no debería hacer

Si un hilo ya tiene un locking, entonces no se bloqueará. El framework .Net lo asegura. Solo tienes que asegurarte de que dos hilos no intenten obtener los mismos dos lockings fuera de secuencia por las rutas de código.

El mismo hilo puede obtener el mismo locking varias veces, pero debes asegurarte de soltar el locking la misma cantidad de veces que lo adquieres. Por supuesto, siempre que use la palabra clave “bloquear” para lograr esto, esto sucede automáticamente.

No, este código no tendrá lockings muertos. Si realmente desea crear el punto muerto más simple, se requieren al menos 2 recursos. Considere el escenario del perro y el hueso. 1. Un perro tiene control total sobre 1 hueso por lo que cualquier otro perro tiene que esperar. 2. Se requiere un mínimo de 2 perros con 2 huesos para crear un interlocking cuando bloquean sus huesos, respectivamente, y buscan otros huesos también.

.. y así sucesivamente n perros y m huesos y causa interlockings más sofisticados.