使用计数信号量实现任务间单向同步

使用计数信号量实现任务间单向同步

概述

计数信号量可以看作上节讲述的二值信号量的增强版,相比二值信号量,计数信号量的取值范围扩大为非负数。

如前所述,二值信号量不能处理“信号积压”问题(如生产者每秒生产5个数据,消费者每秒只能处理1个数据的情况),未及时响应的信号将被新产生的信号替代,使得有效响应的次数少于实际发出的信号次数。在这种情况下,使用计数信号量是一个更合适的选择。

计数信号量适用于:消费者(即接收信号量)的一方虽然不能保证下一次信号到来之前处理完本次信号对应的内容,但是总体上可以响应所有的信号而不会错过某次信号。如生产者每秒生产4个数据,消费者每秒只能处理1个数据的情况,则创建一个最大计数范围为 4 的计数信号量即可,消费者未能及时处理的 4 个数据,将暂存在容量为 4 的计数信号量中不会丢失也不会被覆盖。
在这里插入图片描述
计数信号量也可以用于多个任务之间的同步,完成同时启动、资源回收的同步功能:
在这里插入图片描述

上图显示任务A通过 for 循环多次释放信号量通知任务 B、C 开始工作。
在这里插入图片描述
上图显示任务C通过 for 循环多次接收信号量完成任务 A、任务 B 交代的功能(示例中将演示这种用法)。

此外,计数信号量也可以代表某种资源,被初始化为一个非0值,每次使用一个该资源。其值减去1,代表该条资源已被占用。我们将在资源共享篇详细介绍这种用法。
在这里插入图片描述

需求及功能解析

示例演示了使用计数信号量完成任务间一对一的同步,以及多对一同步的使用方法。

1)在示例中,发送信号的任务1的延时为1s,处理信号的任务2的延时为2s,即每个2s,任务1产生2个信号,任务2处理1个信号,因此,计数信号量的最大取值为3就可以保证任务同步的需求即并且不丢失信号了。

2)任务1、任务2执行完毕后,通知任务3完成信号量回收、清理垃圾资源的功能。

创建计数信号量时使用:

xSemaphoreCreateCounting(uxMaxCount, // 计数信号量的最大值
						uxInitialCount // 计数信号量的初始值
				)

获取、释放信号量的操作与上一节对二值信号量的操作相同,这里不再重复介绍。

示例解析

运行示例中的代码输出 log 如下:

Hello world!
This is esp32 chip with 2 CPU core(s), WiFi/BT/BLE, Minimum free heap size: 295348 bytes
TASK2: task1_flag1 = 1, task2_flag=1
TASK2: task1_flag1 = 2, task2_flag=2
TASK2: task1_flag1 = 4, task2_flag=3
TASK2: task1_flag1 = 6, task2_flag=4
TASK2: task1_flag1 = 6, task2_flag=5
TASK2: task1_flag1 = 6, task2_flag=6
All Done

讨论

在进入任务通信的章节后,一定要注意 RTOS 中存在的一个无形的导演,即任务调度器,任务之间的优先级将是通信后系统整体运行实时性、结果正确性的关键因素之一。感兴趣的小伙伴可以回顾RTOS 中的任务调度与三种任务模型

示例中,接收信号量的任务的优先级>发送信号量的任务的优先级,思考为什么这样安排呢?改变两者的优先级将会发生什么呢?

示例中,同步信号量 sync_count_sem 的最大值为3,试着缩小其最大值,观察测试现象。

总结

1)计数信号量是二值信号量的增强版,在计数范围上,由二值信号量的{0,1}范围,变为{0,非负数}。

2)计数信号量适用于消费者(即接收信号量)的一方虽然不能保证下一次信号到来之前处理完本次信号对应的内容,但是总体上可以响应所有的信号而不会错过某次信号的场景,具备一定的处理信号积压的能力。

3)计数信号量可以完成一对一、多对一、一对多的任务同步功能,还可以用于代表某种共享资源。

资源链接

1)Learning-FreeRTOS-with-esp32 系列博客介绍
2)对应示例的 code 链接 (点击直达代码仓库)

3)下一篇:用事件组实现多事件的单向同步

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

物联网老王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值