zoukankan      html  css  js  c++  java
  • 一种简单的死锁检测算法

    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

  • 相关阅读:
    uva 147 Dollars
    hdu 2069 Coin Change(完全背包)
    hdu 1708 Fibonacci String
    hdu 1568 Fibonacci
    hdu 1316 How Many Fibs?
    poj 1958 Strange Towers of Hanoi
    poj 3601Tower of Hanoi
    poj 3572 Hanoi Tower
    poj 1920 Towers of Hanoi
    筛选法——素数打表
  • 原文地址:https://www.cnblogs.com/deepllz/p/11533860.html
Copyright © 2011-2022 走看看