c++ Multithreaded deadlock situation analysis of contains two generalizations six examples

  • 2020-06-03 07:41:11
  • OfStack

1. What happens to deadlocks

1. Assume the following code


mutex;  // On behalf of 1 A global mutex 
  void A()
   {
     mutex.lock();
     // This is where the operation shares the data 
     B(); // This call B methods 
     mutex.unlock();
     return;
   }
 
  void B()
   {
     mutex.lock();
     // This is where the operation shares the data 
     mutex.unlock();
     return;
   }

At this point, there is a deadlock caused by waiting for unlock in the A and B methods.

2. What is the assumed code


mutex;  // On behalf of 1 A global mutex 
  void A()
   {
     mutex.lock();
     // This is where the operation shares the data 
      if(.....)
     {
       return;
      }
     mutex.unlock();
     return;
   }

Because retun is directly in the execution body of if without calling unlock, a deadlock occurs when another thread calls the A method.

2. Another summary

Whatever the cause, there is a risk of deadlock. So, what are the common deadlocks? We can go one by one and look at it,

(1) Forgetting to release the lock


void data_process() 
{ 
  EnterCriticalSection();  
  if(/* error happens */) 
    return;  
  LeaveCriticalSection(); 
} 

(2) A single thread repeatedly applies for locks


void sub_func() 
{ 
  EnterCriticalSection(); 
  do_something(); 
  LeaveCriticalSection(); 
} 
 
void data_process() 
{ 
  EnterCriticalSection(); 
  sub_func(); 
  LeaveCriticalSection(); 
} 

(3) Double-thread multi-lock application


void data_process1() 
{ 
  EnterCriticalSection(&cs1); 
  EnterCriticalSection(&cs2); 
  do_something1(); 
  LeaveCriticalSection(&cs2); 
  LeaveCriticalSection(&cs1); 
} 
 
void data_process2() 
{ 
  EnterCriticalSection(&cs2); 
  EnterCriticalSection(&cs1); 
  do_something2(); 
  LeaveCriticalSection(&cs1); 
  LeaveCriticalSection(&cs2); 
} 

(4) Ring lock application

[

/*
* A - B
* | |
* C - D
*/

]

Suppose there are four people, A, B, C and D. each of them has one chopstick. So, if one of these people wants to eat, he must first pick up the left chopsticks, then the right chopsticks. Now, we have everyone start eating at the same time. And that's very likely to happen. Everyone picks up the left chopstick, or everyone picks up the right chopstick, in order to eat, they are now waiting for the other chopstick. At this time, everyone wants to eat, and at the same time, no one wants to give up the chopstick he has got. So, in fact, no one can eat.

Conclusion:

(1) The danger of deadlock is always present, but we should try to reduce the scope of the danger
(2) The cost of deadlock resolution is extremely high
(3) The best way to handle deadlocks is to detect them when you write the program
(4) Multithreading is a double-edged sword, with the improvement of efficiency, of course, there is the danger of deadlock
(5) Deadlock is tolerated for some programs, such as restarting the machine, but not for others


Related articles: