本节介绍在处理共享资源的保护问题时,容易引发的一个问题:死锁。

该问题有时比较隐藏,在大多数情况下并不容易出现,而一旦出现,则有可能导致相关的任务卡死。 本节介绍该现像产生的原因、原理及解决方案。

主要内容

死锁现像

两个或两个以上的任务在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。

在视频课程中,我们演示一个死锁的例子,用图来总结该现像如下:
死锁问题及解决 - 图1
在课程中,为了演示方便,源码写的比较简单。在实际的应用中,代码可能就那么简易和直观,而且并不一定每次运行都必然出现死锁。这就可能导致死锁产生只是在某些条件、某些特定时刻下发生,从而导致了其变成一种很潜在的风险。
实际并不限于两个任务,也可存在于更多任务,更多资源。

死锁问题及解决 - 图2

死锁条件

关于死锁产生的条件,操作系统原理书上一般都会列举以下几个条件:

  • 互斥:资源不能被共享,同一时间只能由一个任务使用
  • 请求与保持条件:任务请求资源的同时,持有原有资源不放
  • 非剥夺条件:任务不能强制剥夺另一任务持有的资源
  • 循环等待条件:请求链构成环路,存在循环等待。

以上几个条件,其中互斥、非剥夺一般是我们所用RTOS默认支持,其余条件则由实际应用、程序员编写方式决定。

预防死锁

为了避免死锁产生影响整个系统的运行,有三种方式:

  • 预防:破坏产生的几个条件,容易直观
  • 避免:分配资源前检查,如发生死锁则不分配,避免死锁
  • 检测和恢复:按一定的策略检测是否有死锁,然后恢复

以上几种方式,对我们所用的RTOS而言,一般只能做到预防。而具体的预防措施,其原理在于打破死锁产生的几个条件。
根据前面的【死锁条件】章节介绍,我们只能对控制”请求保持”、”循环等待” 这两个条件施加影响。

具体解决

课程中对于案例采用了两种解决方式:

  • 一性全部分配资源,尽可能避免请求和等待。借助等待资源的超时机制,中间虽有可能发生死锁,但由于超时释放了已申请的资源,避免了超时等待
  • 调整资源申请顺序:避免出现循环等待。

    重点难点

    如果你觉得课程中所介绍的概述、原理等内容不容易理解,那么记住下面这幅图吧。
    死锁问题及解决 - 图3

    注意事项

    常见问题