一種簡單的死鎖檢測算法


1.死鎖檢測

給定一組線程操作鎖的流程,判斷是否會發生死鎖?

例如:有兩個線程和兩個資源,線程對鎖的操作如下:

其中T表示線程id,L表示鎖id,S表示操作(1表示獲取鎖,0表示釋放鎖)

T L S

1 1 1(線程1獲取1號鎖)

2 2 2(線程2獲取2號鎖)

1 2 1(線程1獲取2號鎖,保持等待)

2 1 1(線程2獲取1號鎖,導致死鎖)

如果最后一次操作換為:2 2 0,就不會死鎖.

問題的關鍵是如何判斷死鎖的發生,以上面的例子為例:線程2獲取1號鎖時,發現1號鎖被1號線程占用,那么就要等待線程1釋放1號鎖,然后再看線程1在等待2號鎖,2號鎖被2號線程占用,因此1號線程又要等2號線程釋放2號鎖,這就形成了一個等待環:線程2->線程1->線程2,發生死鎖.所以檢測死鎖的方法就是判斷是否存在這種等待的環路.

對於給定的線程操作鎖的序列:vector<vector<int>> tls,判斷是否發生死鎖要維護3個map,

map<int, int> lock2thread:鎖->線程,標識當前鎖被哪個線程占用

map<int, int> waitedthread2lock:標識當前線程在等待哪個鎖

map<int, vector<int>> thread2locks:標識線程持有的鎖.

偽代碼如下(省去了一些更新和查詢操作):

bool DeadLock(vector<vector<int>> &tls) {
  int size = tls.size();
  map<int, int> lock2thread;
  map<int, int> waitedthread2lock;
  map<int, vector<int>> thread2locks; 
  for(int i = 0; i < size; i++) {
    int tid = tls[i][0];
    int lock = tls[i][1];
    int state = tls[i][2];
    if (state == 0) {
      //釋放鎖,這是一定不會引起死鎖的,因此只需要更新3個map就可以了
      //1.從lock2thread中刪除key==lock的元素
      lock2thread.erase(lock2thread.find(lock));
      //2.從thread2locks中移除lock
      thread2locks[tid].erase(find(thread2locks[tid].begin(), thread2locks[tid].end(),lock));
      //3.遍歷waitedthread2lock,查看哪個線程等待lock
        //3.1如果有線程等待此lock,那么依次更新lock2thread和thread2locks
    } else {
      //說明tid想要獲取lock,那么這個操作是可能導致死鎖的
      if (lock2thread.find(lock) != lock2thread.end()) {
        //說明該鎖已經被占用,那么可能引起死鎖
        int nexttid = 0;//當前線程依賴的下一個線程
        int nextlock = lock;
        while(1) {
          nexttid = lock2thread[nextlock];
          if (nexttid == tid) return true;//發生死鎖
          //查看nexttid在等待哪個資源
          if (waitedthread2lock.find(nexttid) != waitedthread2lock.end()) {
            nextlock = waitedthread2lock[nexttid];
          } else {
            //說明沒有環路,不發生死鎖
            更新waitedthread2lock;
            break;
          }
        }
      } else {
        //說明lock空閑,直接獲取
        更新lock2thread和thread2locks;
        }
    }
  }
}

 2.死鎖預防:銀行家算法

思路很簡單,只有當資源池中有充足的資源時才將資源分配給進程,否則便認為可能存在死鎖的風險.

具體可參考這篇簡單明了的文章:https://zhuanlan.zhihu.com/p/59533950


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM