2010-03-30 17 views
11

¿Alguien puede dar un código de ejemplo de interbloqueo simple en C#? Y, por favor, indique la forma más sencilla de encontrar un punto muerto en su muestra del código C#. (Puede ser la herramienta que detectará el bloqueo de la muerte en el código de ejemplo dado.)muestra de interbloqueo en .net?

NOTA: Tengo VS 2008

+0

@DotNetBeginner: no existe tal cosa como C# .NET. –

+0

Muchas gracias por corregirme: D – DotNetBeginner

Respuesta

18

una forma común es si ha anidado cerraduras que no son adquiridos en el mismo orden . El subproceso 1 podría adquirir el bloqueo A y el subproceso 2 podría adquirir el bloqueo B y bloquearían.

var a = new object(); 
var b = new object(); 

lock(a) { 
    lock(b) { 

    } 
} 

// other thread 
lock (b) { 
    lock(a) { 

    } 
} 

editar: ejemplo no bloqueado .. using waithandles. Supongamos que Sócrates y Descartes están comiendo filetes y que ambos, siendo filósofos bien educados, necesitan un tenedor y un cuchillo para poder comer. Sin embargo, solo tienen un juego de cubiertos, por lo que es posible que cada uno agarre un utensilio y luego espere por siempre a que el otro le entregue el utensilio.

Véase el Dining Philosopher's Problem

WaitHandle fork = new AutoResetEvent(), knife = new AutoResetEvent(); 

while(Socrates.IsHungry) { 
    fork.WaitOne(); 
    knife.WaitOne(); 
    Eat(); 
    fork.Set(); 
    knife.Set(); 
} 

// other thread 
while(Descartes.IsHungry) { 
    knife.WaitOne(); 
    fork.WaitOne(); 
    Eat(); 
    knife.Set(); 
    fork.Set(); 
} 
+0

¿Algún ejemplo sin uso de candado (s)? – DotNetBeginner

+0

¿Qué pasa con la detección de bloqueo muerto cuando ejecuto el código de muestra? – DotNetBeginner

+0

¿Cómo se puede lograr un dead * lock * sin un bloqueo? – Oliver

1

Para el código de ejemplo estancamiento, trate de usar lock(this) en su clase para simular el escenario de estancamiento. Pago this example.

Después de dos artículos dignos de lectura, se detecta el interbloqueo en el tiempo de ejecución y se describen las formas de evitarlos.

  1. Deadlock monitor por Stephen Toub.
  2. TimedLock Again por Ian Griffiths.
+0

+1. Nunca use el candado (esto) – Jimmy

1

Hay una forma más de lograr el punto muerto en C#. Dado que .NET 2.0 SP1 número de subprocesos en el grupo están limitados a 250 (de 25 en la versión anterior) por núcleo.

De manera que, técnicamente, puede iniciar demasiadas tareas en el grupo que esperan completarse para otra operación asincrónica (que se ejecuta a través del grupo de subprocesos). Por lo tanto, la tarea en el grupo no se lanzará y la tarea asíncrona no se iniciará porque no hay subprocesos disponibles.

puede encontrar ejemplo y explicación más precisa aquí: Programming the Thread Pool. Deadlocks

5

Este es un código típico para crear un punto muerto en el código C#. Pedido este artículo de MSDN: http://msdn.microsoft.com/en-us/magazine/cc188793.aspx

using System; 

using System.Threading; 


public class Simple { 

    static object A = new object(); 

    static object B = new object(); 


    static void MethodA() 
    { 
     Console.WriteLine("Inside methodA"); 
     lock (A) 
     { 
      Console.WriteLine("MethodA: Inside LockA and Trying to enter LockB"); 
      Thread.Sleep(5000);   
      lock (B) 
      { 
       Console.WriteLine("MethodA: inside LockA and inside LockB"); 
       Thread.Sleep(5000); 
      } 
      Console.WriteLine("MethodA: inside LockA and outside LockB"); 
     } 
     Console.WriteLine("MethodA: outside LockA and outside LockB"); 
    } 

    static void MethodB() 
    { 
     Console.WriteLine("Inside methodB"); 
     lock (B) 
     { 
      Console.WriteLine("methodB: Inside LockB"); 
      Thread.Sleep(5000); 
      lock (A) 
      { 
       Console.WriteLine("methodB: inside LockB and inside LockA"); 
       Thread.Sleep(5000); 
      } 
      Console.WriteLine("methodB: inside LockB and outside LockA"); 
     } 
     Console.WriteLine("methodB: outside LockB and outside LockA"); 
    } 

    public static void Main(String[] args) 
    { 

     Thread Thread1 = new Thread(MethodA); 
     Thread Thread2 = new Thread(MethodB); 
     Thread1.Start(); 
     Thread2.Start(); 
     Console.WriteLine("enter....."); 
     Console.ReadLine(); 

    } 
} 
1

Para responder a la parte de su pregunta sobre la detección de punto muerto, lo dudo que esto es posible en general. Es similar en cuestión con el problema de detención, no se puede calcular de manera efectiva la semántica. Una forma de superar esto es utilizar un perro guardián que periódicamente sondearía cada hilo si todavía está vivo y le daría un tiempo de espera determinado para responder, si 2 hilos no responden, puede suponer que están ocupados o están muertos- bloqueado

Cuestiones relacionadas