下面是一个基于 ESP32 - S3 实现互斥锁的 C 语言例程,该例程利用 FreeRTOS(ESP32 - S3 所使用的实时操作系统)提供的互斥锁机制,创建两个任务,这两个任务会尝试访问一个共享资源,通过互斥锁来保证同一时间只有一个任务可以访问该资源,避免数据竞争。
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
// 定义一个互斥锁句柄
SemaphoreHandle_t mutex;
// 共享资源
int shared_resource = 0;
// 任务 1 函数
void task1(void *pvParameters) {
while (1) {
// 尝试获取互斥锁
if (xSemaphoreTake(mutex, portMAX_DELAY) == pdTRUE) {
// 成功获取互斥锁,访问共享资源
shared_resource++;
printf("Task 1: Shared resource value = %d\n", shared_resource);
// 释放互斥锁
xSemaphoreGive(mutex);
}
// 任务延时
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
// 任务 2 函数
void task2(void *pvParameters) {
while (1) {
// 尝试获取互斥锁
if (xSemaphoreTake(mutex, portMAX_DELAY) == pdTRUE) {
// 成功获取互斥锁,访问共享资源
shared_resource--;
printf("Task 2: Shared resource value = %d\n", shared_resource);
// 释放互斥锁
xSemaphoreGive(mutex);
}
// 任务延时
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
void app_main() {
// 创建互斥锁
mutex = xSemaphoreCreateMutex();
if (mutex == NULL) {
printf("Failed to create mutex!\n");
return;
}
// 创建任务 1
xTaskCreate(task1, "Task 1", 2048, NULL, 1, NULL);
// 创建任务 2
xTaskCreate(task2, "Task 2", 2048, NULL, 1, NULL);
}
代码说明:
- 互斥锁的创建:在
app_main
函数中,使用xSemaphoreCreateMutex
函数创建一个互斥锁,并将其句柄存储在mutex
变量中。如果创建失败,会输出错误信息。 - 任务的创建:使用
xTaskCreate
函数创建两个任务task1
和task2
,这两个任务会不断循环执行。 - 任务对共享资源的访问:在
task1
和task2
中,使用xSemaphoreTake
函数尝试获取互斥锁。portMAX_DELAY
表示如果互斥锁当前不可用,任务会一直阻塞直到获取到互斥锁。获取到互斥锁后,任务可以安全地访问共享资源shared_resource
,完成操作后使用xSemaphoreGive
函数释放互斥锁。 - 任务延时:使用
vTaskDelay
函数让任务每隔 1 秒执行一次。
编译和运行:
将上述代码保存为 .c
文件,使用 ESP-IDF 开发环境进行编译和烧录,你可以在串口监视器中看到两个任务交替访问共享资源的输出信息。