本章介绍如何使用信号量完成任务的单向同步,此种方式是最简单也是最基础的同步方式。

注,除本课时之外,信号量还可用于其它应用,此处只是介绍了其中一种。

主要内容

这里所提的信号量,指的是计数信号量。

关于计数信号量的具体功能原理,在学习《自己动手从0到1写嵌入式操作系统》课程中,已经给出了流程图,如下。

用信号量实现任务间单向同步 - 图1

有不少同学看了这个流程图之后,仍然不明白究竟应该怎么用。这节课时介绍的就是其中一种应用。

简而言之,有以下几点:

  • 初始化信号量时,计数值设置成0,表示此时还没有收到通知
  • A任务在向B任务发通知时,并不直接通知,而是增加信号量的计数,计数值表明发了多少个通知
  • B任务在信号量上等,一旦发现计数不为0,消耗(减)掉一

如果更具体来讲,可以有以下几种情况。

B任务等待,A任务发通知,B任务恢复运行

  • 在A任务没有发通知之前,信号量计数为0。
  • 当任务B等待通知时,发现计数为0,则在信号量上等待,暂停运行。
  • 之后,当任务A发通知时,检查是否有任务等,发现任务B在等待,恢复任务B为就绪态。
  • 再之后,任务A、B都可以占用CPU继续往下运行各自代码。

视频中举了一个这样的例子:

用信号量实现任务间单向同步 - 图2

A任务发通知,B任务在之后的某个时刻等待信号量,减计数并运行

  • 在A任务没有发通知之前,信号量计数为0。发通知时,发现无任务等待,增加信号量计数。
  • 任务B等待通知时,检查信号量计数,发现计数为非0,则在信号量上等待。如果发现计数为非0,减1计数,继续往下运行其代码。

重点难点

信号量功能

综合来看,计数量信号量提供两大功能:计数值代表发的通知计数;提供无通知时暂停任务运行,有通知时恢复任务运行的功能。

同步方限定

任意任务均可以向信号量发通知,任意任务均可从信号量等通知

课程中只是演示了一对一的同步,实际也可用于一对多、多对一、多对多。以多对多为例:发送通知方并不知道具体哪个任务会收到通知,收到通知的一方并不知道通知由哪个任务发送。

中断与任务的同步

信号量也可用于中断与任务之间同步。中断中向信号量发通知,某任务等待信号量,一旦等待则立即恢复运行。常用于中断处理程序中快速对中断进行简单处理,之后通知任务执行较耗时的处理。

多对多同步

信号量只提供单向同步的功能。如果需要双向同步,可借助两个信号量完成

注意事项

考虑到RTOS中邮箱、事件标志组等功能模块的工作原理,在某种程度上和计数信号量类似,所以在某些情况下,也可以用这些功能模块替代。比如,在某些应用中,当出于裁剪系统功能的需要,可以用这些模块替代计数信号量的功能,实现计数信号量功能代码的裁去。

用信号量实现任务间单向同步 - 图3

常见问题