一种简单的死锁检测算法

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

posted @ 2019-09-17 22:05  灰太狼锅锅  阅读(5166)  评论(0编辑  收藏  举报