2010-03-30 41 views
11

Kann jemand einen einfachen Deadlock-Beispielcode in C# geben? Und bitte sagen Sie den einfachsten Weg, Deadlock in Ihrem C# -Code-Beispiel zu finden. (Kann das Werkzeug sein, die das Riegelschloss in dem gegebenen Beispielcode erkennen.)Deadlock-Beispiel in .net?

HINWEIS: Ich habe VS 2008

+0

@DotNetBeginner: Es gibt nicht so etwas wie C# .NET. –

+0

Vielen Dank für die Korrektur: D – DotNetBeginner

Antwort

18

ein gemeinsamer Weg ist, wenn Sie Schlösser verschachtelt sind, die nicht in der gleichen Reihenfolge erworben werden . Thread 1 könnte Sperre A erhalten und Thread 2 könnte Sperre B erhalten, und sie würden sich blockieren.

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

lock(a) { 
    lock(b) { 

    } 
} 

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

    } 
} 

bearbeiten: Nicht-Sperre Beispiel .. mit Waithandles. Nehmen wir an, Sokrates und Descartes hätten Steaks, und sie beide, gut ausgebildete Philosophen, benötigen sowohl eine Gabel als auch ein Messer, um zu essen. Sie haben jedoch nur einen Satz Silberbesteck, also ist es möglich, dass jeder ein Utensil ergreift und dann für immer darauf wartet, dass der andere sein Utensil übergibt.

die 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

Jedes Beispiel ohne Verwendung von Schloss (s)? – DotNetBeginner

+0

Was ist mit der Erkennung von Dead Lock, wenn ich den Beispielcode starte? – DotNetBeginner

+0

Wie sollte ein totes * Schloss * ohne Schloss erreicht werden? – Oliver

1

Für den Deadlock Beispielcode anzeigen, versuchen lock(this) in Ihrer Klasse mit dem Deadlock-Szenario zu simulieren. Zur Kasse gehen this example.

Nach zwei loyal lesen Artikel erkennt den Deadlock zur Laufzeit und diskutiert Möglichkeiten, sie zu vermeiden.

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

+1. Niemals Schloss benutzen (dies) – Jimmy

1

Es gibt noch einen Weg, um Deadlock in C# zu erreichen. Seit .NET 2.0 SP1 ist die Anzahl der Threads im Pool auf 250 (von 25 in der vorherigen Version) pro Kern begrenzt.

Sie können also technisch zu viele Aufgaben im Pool starten, die auf die Fertigstellung einer anderen asynchronen Operation warten (die über den Thread-Pool ausgeführt wird). Daher wird die Task im Pool nicht freigegeben und die asynchrone Task wird nicht gestartet, da keine Threads verfügbar sind.

Sie können beispiels und genauere Erklärung finden Sie hier: Programming the Thread Pool. Deadlocks

5

Dies ist ein typischer Code ein Deadlock in C# -Code zu erstellen. Kasse dieses MSDN-Artikel: 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

Um den Teil Ihrer Frage zu beantworten Deadlock-Erkennung, bezweifle ich eher, dass dies in der Regel möglich ist. Es ist in der Frage mit dem Halteproblem ähnlich, Sie können die Semantik nicht effektiv berechnen. Eine Möglichkeit, dies zu umgehen, ist die Verwendung eines Watchdogs, der regelmäßig jeden Thread abfragt, wenn er noch aktiv ist, und ihm eine gewisse Zeitüberschreitung gibt. Wenn zwei Threads nicht antworten, können Sie davon ausgehen, dass sie entweder beschäftigt oder tot sind. verschlossen.