创建二值信号量
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