创建二值信号量

static SemaphoreHandle_t xEventSemaphore = NULL;
xEventSemaphore = xSemaphoreCreateBinary();

创建两个任务

注意这里GeneratorTask优先级最高

xTaskCreate(vSemaphoreReceiverTask,"SemReceiver",configMINIMAL_STACK_SIZE,NULL,1,NULL);

xTaskCreate(vSemaphoreGeneratorTask,"SemGenerator",configMINIMAL_STACK_SIZE,NULL,2,NULL);

给出

for(int i = 0;i < 3; i++)
{
	xSemaphoreGive(xEventSemaphore);
}
vTaskDelay(pdMS_TO_TICKS(1000));//需要主动让出CPU,不然Take会出现任务饥饿

这里由于GeneratorTask优先级比ReceiverTask高,所以会执行完这个for,也就是Give三次。

处理

xSemaphoreTake(xEventSemaphore,portMAX_DELAY);

处理的时候只会处理一次

流程

Receiver调用Take
→ Semaphore=0
→ Receiver进入Blocked

Generator运行
→ 第一次Give
→ Semaphore=1
→ Receiver变成Ready
→ 但Receiver优先级低,不能抢占Generator

Generator继续运行
→ 第二次Give
→ Semaphore已经为1
→ Give失败

Generator继续运行
→ 第三次Give
→ Semaphore仍然为1
→ Give失败

Generator调用vTaskDelay
→ Generator进入Blocked

调度器选择Receiver
→ Receiver开始运行
→ Take成功
→ Semaphore从1变成0