.net中的死锁示例?

时间:2010-03-30 06:05:12

标签: c# visual-studio-2008 multithreading deadlock

任何人都可以在c#中提供一个简单的死锁示例代码吗?请告诉您在C#代码示例中找到死锁的最简单方法。 (可能是检测给定示例代码中死锁的工具。)

注意:我有VS 2008

5 个答案:

答案 0 :(得分:18)

一种常见的方法是,如果您具有未以相同顺序获取的嵌套锁。线程1可以获取锁A,线程2可以获取锁B,它们会死锁。

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

lock(a) {
   lock(b) {

   }
}

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

  }
}

编辑:非锁定示例..使用等待句柄。假设苏格拉底和笛卡尔都有牛排,他们都是有礼貌的哲学家,为了吃东西需要叉子和刀子。然而,他们只有一套银器,所以每个人都可以抓住一个器具,然后永远等待对方交出他们的器具。

请参阅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();
} 

答案 1 :(得分: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();

    }
}

答案 2 :(得分:1)

对于死锁示例代码,请尝试在类中使用lock(this)来模拟死锁方案。结帐this example

以下两篇有价值的阅读文章在运行时检测到死锁并讨论了避免死锁的方法。

  1. Deadlock monitor作者:Stephen Toub。
  2. Ian Griffiths的
  3. TimedLock Again

答案 3 :(得分:1)

还有一种方法可以在C#中实现死锁。由于.NET 2.0 SP1中的线程数量限制为每个核心250个(从以前的版本25个)。

因此,从技术上讲,您可以在池中启动太多任务,等待另一个异步操作(通过线程池执行)的完成。因此,池中的任务将不会被释放,并且异步任务将无法启动,因为没有可用的线程。

您可以在此处找到示例和更准确的说明: Programming the Thread Pool. Deadlocks

答案 4 :(得分:1)

要回答有关死锁检测的问题部分,我非常怀疑这通常是可行的。它与暂停问题类似,你无法有效地计算语义。解决这个问题的一种方法是使用一个监视程序,它会定期轮询每个线程,如果它还处于活动状态并给它一定的超时时间,如果2个线程没有响应,你可以认为它们要么忙,要么死了 - 锁定。