2010-03-30 68 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个线程没有响应,你可以假设他们要么忙或者死了 - 锁定。