有一种问题相信大家都不愿碰上,就是低概率偶现问题,这类问题的根源,根据作者的经验常见于以下四种情况:
- 野指针引用
- 数组越界
- 栈溢出
- 临界资源未保护
今天我们说说其中之一的原因:临界资源未保护。
我们先看个例子,假如有一个5个节点单向链表,如下结构:
有一任务A在一个单向链表的2->3节点之间插入一个新的2a节点,已经将2->2a,还未将2a->3,此时,链表变为两个未完整的部分,如下结构:
如此时,任务A被更高优先级的任务B抢占了,并任务B开始访问该链表,那么任务B此次访问就会获得一个错误的结果。
上面的情景就是临界资源未保护导致错误的一种情况,解决这类问题我们通常有两种方法,一种是互斥锁保护,一种是暂时屏蔽中断。
借助这个例子我们先了解几个与临界资源保护相关的概念。
临界资源
临界资源指会被多个任务(或中断)访问到的公共资源。包含软件资源和硬件资源,软件资源指全局变量,如上面例子中的链表,也可能是一个整型数。硬件资源指硬件相关的资源,如spi,I2c总线等。临界资源的访问是需要保证完整的,否则就会出现错误的结果。为了描述方便,下文中出现的‘任务’同时指代任务和中断。
临界区
会访问临界资源的代码片段,在上面的例子中就是指对链表进行增删改查的代码片段,或对硬件总线的访问的代码片段。