互斥量 mutex(临界资源)
大部分情况,线程使用的数据都是局部变量,变量的地址空间在线程栈空间内,这种情况,其他线程无法获得这种变量。
但有时候,很多变量都需要在线程间共享,这样的变量称为共享变量,可以通过数据的共享,完成线程之间的交互。
多个线程并发的操作共享变量,会带来一些问题。
我们为了解决带来的一系列问题,我们需要一把锁。Linux上提供的这把锁叫做互斥量。
#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 mutexHandle;
void Task1(void *pvParam) {
BaseType_t iRet;
while (1) {
printf("task1 begin!\n");
iRet = xSemaphoreTake(mutexHandle, 1000);
if (iRet == pdPASS) {
printf("task1 take!\n");
for (int i = 0; i < 50; i++) {
printf("task1 i=%d\n", i);
vTaskDelay(pdMS_TO_TICKS(1000));
}
xSemaphoreGive(mutexHandle);
printf("task1 give!\n");
vTaskDelay(pdMS_TO_TICKS(5000));
} else {
printf("task1 didn't take!\n");
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
}
void Task2(void *pvParam) {
printf("task2 begin\n");
vTaskDelay(pdMS_TO_TICKS(1000));
while (1) {
}
}
void Task3(void *pvParam) {
BaseType_t iRet;
printf("task3 begin\n");
vTaskDelay(pdMS_TO_TICKS(1000));
while (1) {
iRet = xSemaphoreTake(mutexHandle, 1000);
if (iRet == pdPASS) {
printf("task3 take\n");
for (int i = 0; i < 10; i++) {
printf("task3 i=%d\n", i);
vTaskDelay(pdMS_TO_TICKS(1000));
}
xSemaphoreGive(mutexHandle);
printf("task3 give!\n");
vTaskDelay(pdMS_TO_TICKS(5000));
} else {
printf("task3 didn't take\n");
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
}
void app_main(void) {
mutexHandle = xSemaphoreCreateMutex();
//mutexHandle = xSemaphoreCreateBinary();
vTaskSuspendAll();
xTaskCreate(Task1, "Task1", 1024 * 5, NULL, 1, NULL);
xTaskCreate(Task2, "Task2", 1024 * 5, NULL, 2, NULL);
xTaskCreate(Task3, "Task3", 1024 * 5, NULL, 3, NULL);
xTaskResumeAll();
}
xSemaphoreCreateMutex()创建mutex互斥量,vTaskSuspendAll()挂起任务调度器,使用xTaskCreate()函数创建任务,xTaskResumeAll()恢复任务调度器。