计数型信号量

该博客介绍了计数型信号量在事件计数和资源管理中的使用,以停车场为例,展示了如何通过信号量控制空闲停车位。通过创建计数信号量并调用xSemaphoreGive()和xSemaphoreTake()函数实现车辆进出的同步。在carInTask()任务中,检查并获取信号量以模拟车辆进入,而在carOutTask()任务中,释放信号量表示车辆离开。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

计数型信号量有以下两种典型用法
1.事件计数:每次事件发生,事件处理函数将释放信号量(信号量计数值加1),其他处理任务会获取信号量(信号量计数值减1)来处理事件。因此,计数值是事件发生的数量和事件处理的数量差值。计数信号量在创建时其值为0
2.资源管理:信号量表示有效的资源数目。任务必须先获取信号量才能获取资源控制权。当计数值减为零时表示没有的资源。当任务完成后,它会返还信号量(信号量计数值增加)。信号量创建时计数值应等于最大资源数目。
可以将计数型信号量具体应用在实际场景中:
假设有一家停车场,总共有10个空闲停车位,当一个车放置在停车位中,空闲停车位减少1,当一个车从停车位中开出,空闲停车位增加1,那么计数型信号量就可以理解为空闲停车位,也可以理解为有效地 可以用的资源的数目。

#include <stdio.h>
#include "sdkconfig.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "esp_spi_flash.h"
#include "freertos/queue.h"
#include "freertos/timers.h"
#include "freertos/semphr.h"

SemaphoreHandle_t semaphoreHandle;

void carInTask(void *pvParam) {
	int emptySpace = 0;
	BaseType_t iResult;
	while (1) {
		emptySpace = uxSemaphoreGetCount(semaphoreHandle);
		printf("emptySpace = %d\n", emptySpace);
		iResult = xSemaphoreTake(semaphoreHandle,0);
		if (iResult == pdPASS) {
			printf("one car in\n");
		} else {
			printf("No space\n");
		}
		vTaskDelay(pdMS_TO_TICKS(1000));
	}
}

void carOutTask(void *pvParam) {
	while (1) {
		vTaskDelay(pdMS_TO_TICKS(6000));
		xSemaphoreGive(semaphoreHandle);
		printf("one car out\n");
	}
}

void app_main(void) {
	semaphoreHandle = xSemaphoreCreateCounting(5, 5);
	xSemaphoreGive(semaphoreHandle);
	xTaskCreate(carInTask, "carInTask", 1024 * 5, NULL, 1, NULL);
	xTaskCreate(carOutTask, "carOutTask", 1024 * 5, NULL, 1, NULL);
}

计数型信号量首先要添加信号量头文件freertos/semphr.h。
调用xSemaphoreCreateCounting()函数创建一个计数信号量,并返回信号量可以使用的句柄
引用,调用xSemaphoreGive()函数去释放计数型信号量,调用xTaskCreate()去创建任务。
对于carOutTask()的函数,就去循环去调用xSemaphoreGive()函数去释放信号量,并打印输出。
对于carInTask()的函数,调用uxSemaphoreGetCount()函数获取到计数型信号量的数目,调用xSemaphoreTake()获取信号量。
请添加图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

qq_45671732

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

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

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

打赏作者

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

抵扣说明:

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

余额充值