面试相关——我今天要把死锁弄清楚

死锁

死锁是指由于两个或多个进程(线程同样)互相持有对方所需要的资源,导致这些线程处于等待状态(阻塞现象),没有外力干扰的情况下无法继续执行。互相等待对方释放资源,产生死锁。

产生死锁的必要条件(4个)

1. 资源互斥条件: 进程对于所分配到的资源具有排他性,一个资源只能由一个进程占用,知道该进程释放该资源。

2. 请求保持条件: 进程会请求所有需要的资源,如果过程中因为缺少资源而阻塞,已请求到的资源不会释放。

3. 不可剥夺条件: 进程无法剥夺其他进程的资源,知道其他进程释放资源后才可能请求到。

4. 循环等待条件: 死锁发生时,一定有两个或以上的进程形成环路,在等待下一个进程的某些资源,导致永久阻塞。

这四个条件是死锁产生的必要条件,只要不满足所有四个条件,就不会出现死锁。

举个栗子,两个goroutine各申请两个锁,各占有一个锁的情况下申请另一个导致阻塞。

package main

import (
	"fmt"
	"sync"
	"time"
)

var l1 sync.Mutex
var l2 sync.Mutex

func main() {
	go f1()
	go f2()
	time.Sleep(5 * time.Second)
	fmt.Println("end")
}

func f1() {
	l1.Lock()
	fmt.Println("f1 -- l1 is locking")
	time.Sleep(2 * time.Second)
	l2.Lock()
	fmt.Println("f1 -- l2 locking")
	time.Sleep(2 * time.Second)
	l2.Unlock()
	fmt.Println("f1 -- l2 unlock")
	l1.Unlock()
	fmt.Println("f1 -- l1 unlock")
}

func f2() {
	l2.Lock()
	fmt.Println("f2 -- l2 is locking")
	time.Sleep(2 * time.Second)
	l1.Lock()
	fmt.Println("f2 -- l1 locking")
	time.Sleep(2 * time.Second)
	l1.Unlock()
	fmt.Println("f2 -- l1 unlock")
	l2.Unlock()
	fmt.Println("f2 -- l2 unlock")
}


Print:
f1 -- l1 is locking
f2 -- l2 is locking
end

 

下面是比较容易混淆的概念(面试题中,有时候会搞混)

预防死锁(确保系统不会进入死锁状态)

死锁预防,只要能做到不让上述四个条件全部达成就可以。其中互斥条件最好不要动。

1.破坏请求保持    进程开始运行前,一次性申请全部资源。优势:简单易用安全。劣势:资源利用率下降。

2.破坏不可剥夺    进程请求资源过程中,遇到无法获得的资源,释放所有已获得的资源。 劣势:实现复杂,增加系统开销。

3.破坏循环等待    对系统资源进行排序(顺序分配资源法) 劣势:资源浪费,不易实现。

避免死锁(判断,只允许不产生死锁的进程申请资源)

避免死锁比预防死锁的限制小,但是必须事先声明每个进程的最大资源量,分配资源数目是固定的。

1. 一次封锁法:  一次分配所有资源

2. 顺序封锁法:  固定顺序分配资源。      劣势:必须实现知道所有可能用到的锁,并且要知道获取顺序。

3. 加锁时限法:  设置时钟,到达时钟仍然无法获得资源就释放资源。    劣势:资源浪费,甚至可能系统情况越来越糟。

3. 银行家算法(常用)

检测死锁

这部分是根据现有进程的所需资源画图进行分配预演。

根据进程画出资源分配图,简化资源分配图,使用死锁定理判断。

死锁定理: 系统没有环路,则没有死锁,否则,可能存在死锁。

解除死锁

1. 抢占资源: 从一个或多个进程中抢占足够数量的资源分配给死锁进程,以解除死锁状态。这时可能挂起某些死锁进程,将这些资源分配给其他的死锁进程。但应防止被挂起的进程长时间得不到资源,而处于资源匮乏的状态。

2. 撤销进程: 强制撤销部分、甚至全部死锁进程并剥夺这些进程的资源。撤销的原则可以按进程优先级和撤销进程代价的高低进行。

3. 进程回退: 让一(多)个进程回退到足以回避死锁的地步,进程回退时自愿释放资源而不是被剥夺。要求系统保持进程的历史信息,设置还原点。

 


记录每天解决的小问题,积累起来去解决大问题

 

 

 

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Lazyboy_/article/details/89458125

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值