c++多線程之死鎖的發生的情況解析(包含兩個歸納,6個示例)

一、死鎖會在什麼情況發生

1、假設有如下代碼

   mutex;   //代表一個全局互斥對象

   void  A()

      {

          mutex.lock();

          //這裏操作共享數據

          B();  //這裏調用B方法

          mutex.unlock();

         return;

      }

 

   void  B()

      {

          mutex.lock();

          //這裏操作共享數據

          mutex.unlock();

         return;

      }

此時會由於在A、B方法中相互等待unlock而導致死鎖。

2、假設有如何代碼

   mutex;   //代表一個全局互斥對象

   void  A()

      {

          mutex.lock();

          //這裏操作共享數據

           if(.....)

          {

              return;

           }

         mutex.unlock();

         return;

      }

由於在if的執行體內直接retun,而沒有調用unlock,導致另一個線程再調用A方法就出現死鎖。


二、另一個總結

   不管什麼原因,死鎖的危機都是存在的。那麼,通常出現的死鎖都有哪些呢?我們可以一個一個看過來,

    (1)忘記釋放鎖

  1. void data_process()  
  2. {  
  3.     EnterCriticalSection();  
  4.   
  5.     if(/* error happens */)  
  6.         return;  
  7.   
  8.     LeaveCriticalSection();  
  9. }  
    (2)單線程重複申請鎖

  1. void sub_func()  
  2. {  
  3.     EnterCriticalSection();  
  4.     do_something();  
  5.     LeaveCriticalSection();  
  6. }  
  7.   
  8. void data_process()  
  9. {  
  10.     EnterCriticalSection();  
  11.     sub_func();  
  12.     LeaveCriticalSection();  
  13. }  
    (3)雙線程多鎖申請
  1. void data_process1()  
  2. {  
  3.     EnterCriticalSection(&cs1);  
  4.     EnterCriticalSection(&cs2);  
  5.     do_something1();  
  6.     LeaveCriticalSection(&cs2);  
  7.     LeaveCriticalSection(&cs1);  
  8. }  
  9.   
  10. void data_process2()  
  11. {  
  12.     EnterCriticalSection(&cs2);  
  13.     EnterCriticalSection(&cs1);  
  14.     do_something2();  
  15.     LeaveCriticalSection(&cs1);  
  16.     LeaveCriticalSection(&cs2);  
  17. }  
    (4)環形鎖申請
  1. /* 
  2. *             A   -  B 
  3. *             |      | 
  4. *             C   -  D 
  5. */  

    假設有A、B、C、D四個人在一起吃飯,每個人左右各有一隻筷子。所以,這其中要是有一個人想吃飯,他必須首先拿起左邊的筷子,再拿起右邊的筷子。現在,我們讓所有的人同時開始吃飯。那麼就很有可能出現這種情況。每個人都拿起了左邊的筷子,或者每個人都拿起了右邊的筷子,爲了吃飯,他們現在都在等另外一隻筷子。此時每個人都想吃飯,同時每個人都不想放棄自己已經得到的一那隻筷子。所以,事實上大家都吃不了飯。

總結:
    (1)死鎖的危險始終存在,但是我們應該儘量減少這種危害存在的範圍
    (2)解決死鎖花費的代價是異常高昂的
    (3)最好的死鎖處理方法就是在編寫程序的時候儘可能檢測到死鎖
    (4)多線程是一把雙刃劍,有了效率的提高當然就有死鎖的危險
    (5)某些程序的死鎖是可以容忍的,大不了重啓機器,但是有些程序不行


發佈了68 篇原創文章 · 獲贊 140 · 訪問量 92萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章