Can someone give an example of how thread deadlock can be caused in the C# language?
A deadlock is a situation in which two computer programs sharing the same resource are effectively preventing each other from accessing the resource, resulting in both programs ceasing to function.
Deadlock is a situation where two or more processes are waiting for each other. For example, let us assume, we have two processes P1 and P2. Now, process P1 is holding the resource R1 and is waiting for the resource R2. At the same time, the process P2 is having the resource R2 and is waiting for the resource R1.
Deadlock describes a condition in which two or more threads are blocked (hung) forever because they are waiting for each other. There are many causes of deadlocks. The Thread Analyzer detects deadlocks that are caused by the inappropriate use of mutual exclusion locks.
One of the most common ways of avoiding a deadlock is to always lock the two mutexes in the same order. If we always lock mutex A before mutex B, then we'll never have a deadlock.
static object object1 = new object(); static object object2 = new object(); public static void ObliviousFunction() { lock (object1) { Thread.Sleep(1000); // Wait for the blind to lead lock (object2) { } } } public static void BlindFunction() { lock (object2) { Thread.Sleep(1000); // Wait for oblivion lock (object1) { } } } static void Main() { Thread thread1 = new Thread((ThreadStart)ObliviousFunction); Thread thread2 = new Thread((ThreadStart)BlindFunction); thread1.Start(); thread2.Start(); while (true) { // Stare at the two threads in deadlock. } }
From Threading in C#
At the other end of the scale, separate synchronization contexts invite deadlocks. Here's an example:
[Synchronization] public class Deadlock : ContextBoundObject { public DeadLock Other; public void Demo() { Thread.Sleep (1000); Other.Hello(); } void Hello() { Console.WriteLine ("hello"); } } public class Test { static void Main() { Deadlock dead1 = new Deadlock(); Deadlock dead2 = new Deadlock(); dead1.Other = dead2; dead2.Other = dead1; new Thread (dead1.Demo).Start(); dead2.Demo(); }
Because each instance of Deadlock is created within Test – an unsynchronized class – each instance will gets its own synchronization context, and hence, its own lock. When the two objects call upon each other, it doesn't take long for the deadlock to occur (one second, to be precise!) The problem would be particularly insidious if the Deadlock and Test classes were written by different programming teams. It may be unreasonable to expect those responsible for the Test class to be even aware of their transgression, let alone know how to go about resolving it. This is in contrast to explicit locks, where deadlocks are usually more obvious.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With