Multithreaded dead lock

I tried to create an example of a dead end. I tried the following code. But instead of creating a dead end, it worked like a charm. Help me understand why he did not create a dead end. What change in this code will create a dead end?

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace ReferenceTypes { class DeadLockExample { static int a; static int b; public static void Main(string[] args) { DeadLockExample.a = 20; DeadLockExample.b = 30; DeadLockExample d = new DeadLockExample(); Thread tA = new Thread(new ThreadStart(d.MethodA)); Thread tB = new Thread(new ThreadStart(d.MethodB)); tA.Start(); tB.Start(); Console.ReadLine(); } private void MethodA() { lock (this) { Console.WriteLine(a); Thread.Sleep(1000); Console.WriteLine(b); } } private void MethodB() { lock (this) { Console.WriteLine(b); Thread.Sleep(1000); Console.WriteLine(a); } } } } 
+7
multithreading c #
source share
4 answers

As everyone else said, two locks are acquired in different orders, so that each is waiting for each other. I also changed one of the sleep lengths to provide a high probability of a dead end.

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace ReferenceTypes { class DeadLockExample { static int a; static int b; static object lockedObjA = new object(); static object lockedObjB = new object(); public static void Main(string[] args) { DeadLockExample.a = 20; DeadLockExample.b = 30; DeadLockExample d = new DeadLockExample(); Thread tA = new Thread(new ThreadStart(d.MethodA)); Thread tB = new Thread(new ThreadStart(d.MethodB)); tA.Start(); tB.Start(); Console.ReadLine(); } private void MethodA() { lock (DeadLockExample.lockedObjA) { Console.WriteLine(a); Thread.Sleep(1200); lock (DeadLockExample.lockedObjB) { Console.WriteLine(b); } } } private void MethodB() { lock (DeadLockExample.lockedObjB) { Console.WriteLine(b); Thread.Sleep(1000); lock (DeadLockExample.lockedObjA) { Console.WriteLine(a); } } } } } 
+11
source share

2 locks, 2 streams.

Thread A takes lock A, sleeps, and then tries to lock B. Thread B takes lock B, sleeps and then tries to lock A to a deadlock.

[Thread A needs to sleep long enough for thread B to block B before thread A tries to get it]

+3
source share

Here are three different ways to turn off a dead end. This list is not exhaustive.

Call the lock method from the lock section.

In this example, thread A gets a lock, and then immediately calls the lock method, while thread B tries to get the same lock, but gets a hang because thread A waits for thread B to signal an event before it will release the lock.

 public class Example { ManualResetEvent m_Event = new ManualResetEvent(false); void ThreadA() { lock (this) { m_Event.WaitOne(); } } void ThreadB() { lock (this) { m_Event.Set(); } } } 

Get two locks out of order.

No explanation is required here, as this is a well-known problem.

 public class Example { private object m_LockObjectA = new object(); private object m_LockObjectB = new Object(); void ThreadA() { lock (m_LockObjectA) lock (m_LockObjectB) { } } void ThreadB() { lock (m_LockObjectB) lock (m_LockObjectA) { } } } 

Lockable dead end.

This is one of my favorite illustrations of the dead end because the lock or block method is not involved. The subtleties of the problem are enough to confuse even those who are familiar with threads. The problem here is the lack of memory barriers. Thread A expects thread B to set a signal flag, while thread B waits for thread A to reset all the time until one thread sees the changes that the other makes, because the compiler, JIT, and hardware are free to optimize reading and writing flag in a way that is not intuitive.

 public class Example { private bool m_Signal = false; void ThreadA() { while (!m_Signal); m_Signal = false; } void ThreadB() { m_Signal = true; while (m_Signal); } } 
+1
source share

From Wikipedia -

A dead end is a situation in which two or more competing actions are waiting for the other to finish, and thus never happen.

You do not fulfill this requirement with your code above - there will never be an end when both threads A and thread B are waiting for each other.

0
source share

All Articles