新人,有问题欢迎大佬指正,立马改
一、死锁产生的原因
系统给进程分配的资源是有限的,有一些资源需要互斥访问,此时可能会出现一种情况,两个进程都分配了一些需互斥访问的资源,但是这些资源并不足以让这两个进程都满足执行条件,并且他们都需要分配给对方的互斥访问资源才可以运行,他们都不释放资源,且都持续进行资源申请,不允许其他进程对自身的资源进行剥夺,进入循环等待的状态,此时该即为死锁。
二、死锁产生的必要条件
由上面的例子可知产生死锁的条件有四条即
1.互斥条件
互斥访问即有些资源需要互斥访问
2.请求并保持条件
请求并保持条件,即一个进程要申请新的资源,并且持续不断的申请
3.不剥夺条件
不允许其他进程来剥夺自身已经获得的资源
4.循环等待条件
进程不满足执行条件时一直循环等待
三、预防死锁
上面我们已经知道了死锁产生的四个必要条件,此时为了避免死锁状态的产生,可以破坏死锁产生的条件。因为有些资源是必须要互斥访问的(例如:打印机,若不互拆访问,则可能会出现两个进程互相抢夺打印的情况产生,因此必须互斥访问),因此我们只可以破坏的死锁的四个必要条件中的后三个。
1.破坏请求并保持条件
在系统进行资源分配时一次性将该进程所需要的所有资源都分配给它,因此破坏了请求条件,如果当前系统的资源不足以分配,那就让它等待,破坏了持续条件,因此可以预防死锁的产生
优点:简单易实现。
缺点:资源浪费严重,进程执行延迟(因所需资源不够一直不能执行)。
2.破坏不剥夺条件
当一个进程已经拥有一些资源的时候,此时又申请新的资源而不被满足的时候,就必须释放它已经获得的资源,需要时再申请,此时就破坏了不剥夺条件。
优点:释放了被占用的资源。
缺点:反复释放申请进程所需资源,系统开销大。
3.破坏循环等待条件
系统将所有资源按类型进行排队,并赋予不同序号,对进程申请分配的资源按照序号来分配。
优点:资源利用率上升。
缺点:不灵活,如果加入新的设备还需要编号。
四、系统安全状态
在资源分配之前,要先计算资源分配的安全性,即进程执行的顺序,以确保这些进程执行过程中不会出现死锁的现象,如果存在这种执行顺序则系统就处于安全状态,否则则处于不安全状态,不安全状态可能会出现死锁现象。
五、避免死锁
使用银行家算法来避免出现死锁的情况,银行家算法其中有可利用的资源向量Available,里面每个元素代表当前可使用的资源数,最大需求矩阵(MAX)每个元素表示不同进程对各个资源的需求量,分配矩阵(Allocation),里面每个元素为当前已经分配给各个进程的资源数,需求矩阵(Need),此中元素为当前各个进程还需要的资源数,即MAX-Allocation 。
银行家算法执行步骤
1.先判断进程需要的资源数是否超过所需的最大值,否则继续执行,是则错误。
2.判断进程所需的资源是否小于剩余资源数,是则继续,否则该进程等待。
3.尝试把资源分配给进程,并对相对应的矩阵进行修改。
4.判断所有进程是否存在安全序列,有则分配资源,没有则不分配。
下面是一个使用Python实现银行家算法的代码示例:
```python
# 定义银行家算法函数,传入参数:available表示可用资源,maximum表示各进程所需最大资源,allocation表示各进程已分配资源,need表示各进程还需要的资源
def banker_algorithm(available, maximum, allocation, need):
# 初始化工作
n_processes = len(allocation)
work = available.copy()
finish = [False] * n_processes
safe_seq = []
while True:
# 查找满足条件的进程,满足条件的进程指的是需要资源少于等于可用资源的进程,并且没有完成
found = False
for i in range(n_processes):
if not finish[i] and all(need[i][j] <= work[j] for j in range(len(available))):
found = True
break
if not found:
break
# 为满足条件的进程分配资源,并将其标记为已完成
for j in range(len(available)):
work[j] += allocation[i][j]
finish[i] = True
safe_seq.append(i)
# 判断是否存在安全序列
if all(finish):
return safe_seq
else:
return None
```
使用示例:
```python
available = [3, 3, 2]
maximum = [
[7, 5, 3],
[3, 2, 2],
[9, 0, 2],
[2, 2, 2],
[4, 3, 3]
]
allocation = [
[0, 1, 0],
[2, 0, 0],
[3, 0, 2],
[2, 1, 1],
[0, 0, 2]
]
need = [
[7, 4, 3],
[1, 2, 2],
[6, 0, 0],
[0, 1, 1],
[4, 3, 1]
]
safe_seq = banker_algorithm(available, maximum, allocation, need)
if safe_seq is not None:
print("存在安全序列:", safe_seq)
else:
print("不存在安全序列")
```
输出:
```
存在安全序列: [1, 3, 4, 0, 2]
```
六、检测死锁
用资源分配图进行死锁检测
方块代表资源,里面的黑点代表资源个数,圆形为进程,方块指向圆形的箭头表示已经分配了一个资源,圆形指向方块的箭头代表申请资源。
死锁检测在计算机科学中有以下应用:
1. 操作系统:操作系统中的进程可能会因为竞争资源而陷入死锁状态。死锁检测技术能够检测这种状态并采取相应的措施,例如释放资源或者终止进程,以解除死锁。
2. 数据库管理系统:数据库中的事务也可能因为竞争资源而陷入死锁状态。死锁检测技术能够检测这种状态并采取相应的措施,例如回滚事务或者释放锁,以解除死锁。
3. 分布式系统:分布式系统中的多个节点之间可能因为竞争资源而陷入死锁状态。死锁检测技术能够检测这种状态并采取相应的措施,例如协调资源访问,以解除死锁。
4. 网络协议:网络中的协议也可能因为竞争资源而陷入死锁状态。死锁检测技术能够检测这种状态并采取相应的措施,例如重置连接或者终止会话,以解除死锁。
总的来说,死锁检测技术在计算机系统中有广泛的应用,能够帮助系统解决资源竞争带来的死锁问题,保障系统的正常运行。
七、死锁的解除
1.剥夺资源 :从其他进程剥夺当前进程所需的资源数量,解除死锁
2.撤销进程:撤销进程,直到有足够的资源解除死锁