本节介绍在处理共享资源的保护问题时,容易引发的一个问题:死锁。
该问题有时比较隐藏,在大多数情况下并不容易出现,而一旦出现,则有可能导致相关的任务卡死。 本节介绍该现像产生的原因、原理及解决方案。
主要内容
死锁现像
两个或两个以上的任务在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。
在视频课程中,我们演示一个死锁的例子,用图来总结该现像如下:
在课程中,为了演示方便,源码写的比较简单。在实际的应用中,代码可能就那么简易和直观,而且并不一定每次运行都必然出现死锁。这就可能导致死锁产生只是在某些条件、某些特定时刻下发生,从而导致了其变成一种很潜在的风险。
实际并不限于两个任务,也可存在于更多任务,更多资源。
死锁条件
关于死锁产生的条件,操作系统原理书上一般都会列举以下几个条件:
- 互斥:资源不能被共享,同一时间只能由一个任务使用
- 请求与保持条件:任务请求资源的同时,持有原有资源不放
- 非剥夺条件:任务不能强制剥夺另一任务持有的资源
- 循环等待条件:请求链构成环路,存在循环等待。
以上几个条件,其中互斥、非剥夺一般是我们所用RTOS默认支持,其余条件则由实际应用、程序员编写方式决定。
预防死锁
为了避免死锁产生影响整个系统的运行,有三种方式:
- 预防:破坏产生的几个条件,容易直观
- 避免:分配资源前检查,如发生死锁则不分配,避免死锁
- 检测和恢复:按一定的策略检测是否有死锁,然后恢复
以上几种方式,对我们所用的RTOS而言,一般只能做到预防。而具体的预防措施,其原理在于打破死锁产生的几个条件。
根据前面的【死锁条件】章节介绍,我们只能对控制”请求保持”、”循环等待” 这两个条件施加影响。
具体解决
课程中对于案例采用了两种解决方式: