Question

Can anybody give a simple Deadlock sample code in c# ? And please tell the simplest way to find deadlock in your C# code sample. (May be the tool which will detect the dead lock in the given sample code.)

NOTE: I have VS 2008

No correct solution

OTHER TIPS

one common way is if you have nested locks that aren't acquired in the same order. Thread 1 could acquire lock A and thread 2 could acquire lock B and they would deadlock.

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

lock(a) {
   lock(b) {

   }
}

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

  }
}

edit: non-lock example .. using waithandles. Suppose Socrates and Descartes are having steaks and they both, being well-mannered philosophers, require both a fork and a knife in order to eat. However, they have only one set of silverware, so it is possible for each to grab one utensil and then wait forever for the other to hand over their utensil.

See the 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();
} 

This is a typical code to create a deadlock in C# code. Checkout this MSDN article: 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();

    }
}

For the deadlock sample code, try using lock(this) in your class to simulate the deadlock scenario. Checkout this example.

Following two worthy reading articles detects the deadlock at runtime and discusses ways to avoid them.

  1. Deadlock monitor by Stephen Toub.
  2. TimedLock Again by Ian Griffiths.

There is one more way to achieve deadlock in C#. Since .NET 2.0 SP1 number of threads in pool are limited to 250 (from 25 in previous version) per core.

So, techically, you can start too many tasks in pool that wait for completion for another async operation (that is executed through thread pool). Therefore, task in pool will not be released and async task will not start because there are no available threads.

You can find example and more precise explanation here: Programming the Thread Pool. Deadlocks

To answer the part of your question about deadlock detection, I rather doubt that this is in general possible. It is similar in question with the halting problem, you cannot effectively compute the semantics. One way to overcome this is to use a watchdog which would periodically poll each thread if it is still alive and give it a certain timeout to answer, if 2 threads do not respond, you can assume they are either to busy or they are dead-locked.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow