2010-03-30 106 views
11

任何人都可以在c#中給一個簡單的死鎖示例代碼?請告訴最簡單的方法來找到C#代碼示例中的死鎖。 (可能是工具,它會檢測指定的示例代碼死鎖。).net中的死鎖示例?

注:我有2008 VS

+0

@DotNetBeginner:沒有C#.NET這樣的東西。 – 2010-03-30 06:14:40

+0

非常感謝您糾正我:D – DotNetBeginner 2010-03-30 06:19:12

回答

18

一個常見的方式是,如果你有嵌套未以相同的順序獲取的鎖。線程1可以獲得鎖A,線程2可以獲得鎖B並且它們會死鎖。

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

lock(a) { 
    lock(b) { 

    } 
} 

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

    } 
} 

編輯:非鎖定示例..使用waithandles。假設蘇格拉底和笛卡爾有牛排,而他們兩個都是優雅的哲學家,都需要叉子和刀才能吃。但是,他們只有一套銀器,所以每個人都可以抓住一個器具,然後永遠等待另一個器具移交。

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

沒有使用鎖的示例? – DotNetBeginner 2010-03-30 06:14:05

+0

當我運行您的示例代碼時,檢測死鎖的情況如何? – DotNetBeginner 2010-03-30 06:34:45

+0

如何在不鎖定的情況下實現死鎖? – Oliver 2010-03-30 06:46:53

1

對於僵局示例代碼,嘗試在你的類使用lock(this)模擬死鎖情況。結帳this example

以下兩篇值得閱讀的文章在運行時檢測到死鎖,並討論避免它們的方法。

  1. Deadlock monitor Stephen Toub。
  2. TimedLock Again作者:Ian Griffiths。
+0

+1。永遠不要使用鎖(這個) – Jimmy 2010-03-30 06:40:11

1

還有一種方法可以在C#中實現死鎖。由於.NET 2.0 SP1中的線程數量限於每個核心250(從以前的版本25)。

因此,從技術上講,您可以在池中啓動太多的任務,等待另一個異步操作(通過線程池執行)完成。因此,池中的任務不會被釋放,並且異步任務將不會啓動,因爲沒有可用的線程。

你可以找到例子,這裏更精確的解釋: Programming the Thread Pool. Deadlocks

5

這是一個典型的代碼來創建在C#代碼中的僵局。 結帳這個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

要獲得關於死鎖檢測問題的一部分,我相當懷疑,這是一般的可能。它與暫停問題類似,你不能有效地計算語義。解決這個問題的一個方法是使用一個監視器,它會週期性地輪詢每個線程是否仍然活着,並給它一定的超時時間來回答,如果2個線程沒有響應,你可以假設他們要麼忙或者死了 - 鎖定。