死锁_gc376i6289ffbvt6

    720
    最后修改于

    原因:资源竞争、同步互斥不当
    条件:互斥、不剥夺、请求并保持、循环等待

    死锁预防#

    互斥条件:不可破坏
    不剥夺条件:抢占资源(如 CPU,内存),但是不适用于打印机这类资源
    请求并保持条件:运行前一次申请所有资源,不满足就不运行,导致饥饿,资源浪费
    循环等待条件:顺序资源分配,给资源编号,必须按顺序请求资源,同类资源一次申请完。这种情况编号必须稳定,在资源新增时会被限制,资源浪费

    死锁避免#

    动态申请,单分配前计算安全性,防止进入不安全状态。如果不会进入不安全状态就分配。
    银行家算法:系统按照某种进程推进顺序,分配所需资源,直到满足每个进程最大需求,每个进程都可完成。此时称为一个安全序列,如果无法找到一个安全序列,则是不安全状态。

    检测与解除#

    资源分配图
    image.png
    死锁定理:在分配图中,找出既不阻塞,又不孤点的进程 P,消除分配边和请求边。视为释放了资源,依次做,如果能够消除所有边就称为可完全简化。否则则是出现死锁。
    解除:资源剥夺,进程撤销,进程回退(需要还原点)。

    银行家算法#

    image.png
    输入:可用资源向量 Avaliable,进程已分配资源向量 Allocation,进程最大需求资源向量 Max
    当进程发起请求 Request 时,如果 Request < Avaliable,继续,否则等待
    尝试分配
    Avaliable = Avaliable - Request
    Allocation = Allocation + Request
    用安全性算法检查此次分配之后,是否处于安全状态。

    kotlin
    class PRes(
        val MaxNeed: List<Int>
        val Allocation: List<Int>
        val Need: List<Int>
    ){
        fun allocable(avaliable List<Int>):Boolean {
            for i in avaliable {
                if (avaliable[i] - Need[i] < 0){
                    return false
                }
            }
            return true
        }
        fun release(avaliable List<Int>):List<Int>{
            for i in avaliable {
                avaliable[i] += allocation[i]
            }
            return avaliable
        }
    }
    fun safe(pSet: List<PRes>){    
        safeSeq = emptyList()    
        while (true) {
            // 从 Need 中找出不在安全序列中
            // 且该行小于 Available 的进程加入安全序列
            val p = pSet.find { it.allocable(Available) }
    	    if (p != null) {
                safeSeq.add(p)
                // 假设进入安全序列的进程顺利完成
                // 返回已分配的资源
                Available = p.release(Available)
    	        needSet.remove(p)
            }else {
                break
            }
        }
        return needSet.isEmpty()
    }
    

    #
    • 🥳0
    • 👍0
    • 💩0
    • 🤩0