哈尔滨市做淘宝的网站关键词搜索优化公司
文章目录
- 前言
- 一、互斥量与二进制信号量
- 二、优先级反转与优先级继承
- 三、递归锁
前言
通过学习上一章互斥量理论基础,这一章我们来做一些实验进行验证。
一、互斥量与二进制信号量
互斥量使用和二进制信号量类似
- 互斥量有优先级继承功能,二进制信号量没有
- Give/Take函数完全一样
- 二进制信号量的初始值是0,互斥量的初始值是1
二、优先级反转与优先级继承
首先创建三个优先级不同的任务
xTaskCreate( vLPTask, "LPTask", 1000, NULL, 1, NULL );xTaskCreate( vMPTask, "MPTask", 1000, NULL, 2, NULL );xTaskCreate( vHPTask, "HPTask", 1000, NULL, 3, NULL );
创建互斥量/二进制信号量
SemaphoreHandle_t xLock;
// xLock = xSemaphoreCreateBinary( );xLock = xSemaphoreCreateMutex( );xSemaphoreGive(xLock);
三个优先级不同的任务处理不同事情,验证二进制信号量的优先级反转和互斥量的优先级继承功能
/*-----------------------------------------------------------*/
static void vLPTask( void *pvParameters )
{const TickType_t xTicksToWait = pdMS_TO_TICKS( 10UL ); uint32_t i;char c = 'A';printf("LPTask start\r\n");/* 无限循环 */for( ;; ){ flagLPTaskRun = 1;flagMPTaskRun = 0;flagHPTaskRun = 0;/* 获得互斥量/二进制信号量 */xSemaphoreTake(xLock, portMAX_DELAY);/* 耗时很久 */printf("LPTask take the Lock for long time");for (i = 0; i < 26; i++) {flagLPTaskRun = 1;flagMPTaskRun = 0;flagHPTaskRun = 0;printf("%c", c + i);}printf("\r\n");/* 释放互斥量/二进制信号量 */xSemaphoreGive(xLock);vTaskDelay(xTicksToWait);}
}static void vMPTask( void *pvParameters )
{const TickType_t xTicksToWait = pdMS_TO_TICKS( 30UL ); flagLPTaskRun = 0;flagMPTaskRun = 1;flagHPTaskRun = 0;printf("MPTask start\r\n");/* 让LPTask、HPTask先运行 */ vTaskDelay(xTicksToWait);/* 无限循环 */for( ;; ){ flagLPTaskRun = 0;flagMPTaskRun = 1;flagHPTaskRun = 0;}
}static void vHPTask( void *pvParameters )
{const TickType_t xTicksToWait = pdMS_TO_TICKS( 10UL ); flagLPTaskRun = 0;flagMPTaskRun = 0;flagHPTaskRun = 1;printf("HPTask start\r\n");/* 让LPTask先运行 */ vTaskDelay(xTicksToWait);/* 无限循环 */for( ;; ){ flagLPTaskRun = 0;flagMPTaskRun = 0;flagHPTaskRun = 1;printf("HPTask wait for Lock\r\n");/* 获得互斥量/二进制信号量 */xSemaphoreTake(xLock, portMAX_DELAY);flagLPTaskRun = 0;flagMPTaskRun = 0;flagHPTaskRun = 1;/* 释放互斥量/二进制信号量 */xSemaphoreGive(xLock);}
}/*-----------------------------------------------------------*/
二进制信号量 实现优先级反转,中优先级先于高优先级执行
互斥量实现优先级继承
三、递归锁
创建递归锁
/* 递归锁句柄 */
SemaphoreHandle_t xMutex;xMutex = xSemaphoreCreateRecursiveMutex( );
创建2个任务: 一个上锁, 另一个自己监守自盗(开别人的锁自己用)
xTaskCreate( vTakeTask, "Task1", 1000, NULL, 2, NULL );xTaskCreate( vGiveAndTakeTask, "Task2", 1000, NULL, 1, NULL );/* 启动调度器 */vTaskStartScheduler();
任务描述
/*-----------------------------------------------------------*/
static void vTakeTask( void *pvParameters )
{const TickType_t xTicksToWait = pdMS_TO_TICKS( 100UL ); BaseType_t xStatus;int i;/* 无限循环 */for( ;; ){ /* 获得递归锁: 上锁 */xStatus = xSemaphoreTakeRecursive(xMutex, portMAX_DELAY);printf("Task1 take the Mutex in main loop %s\r\n", \(xStatus == pdTRUE)? "Success" : "Failed");/* 阻塞很长时间, 让另一个任务执行, * 看看它有无办法再次获得递归锁 */vTaskDelay(xTicksToWait);for (i = 0; i < 10; i++){/* 获得递归锁: 上锁 */xStatus = xSemaphoreTakeRecursive(xMutex, portMAX_DELAY);printf("Task1 take the Mutex in sub loop %s, for time %d\r\n", \(xStatus == pdTRUE)? "Success" : "Failed", i);/* 释放递归锁 */xSemaphoreGiveRecursive(xMutex);}/* 释放递归锁 */xSemaphoreGiveRecursive(xMutex);}
}static void vGiveAndTakeTask( void *pvParameters )
{const TickType_t xTicksToWait = pdMS_TO_TICKS( 10UL ); BaseType_t xStatus;/* 尝试获得递归锁: 上锁 */xStatus = xSemaphoreTakeRecursive(xMutex, 0);printf("Task2: at first, take the Mutex %s\r\n", \(xStatus == pdTRUE)? "Success" : "Failed");/* 如果失败则监守自盗: 开锁 */if (xStatus != pdTRUE){/* 无法释放别人持有的锁 */xStatus = xSemaphoreGiveRecursive(xMutex);printf("Task2: give Mutex %s\r\n", \(xStatus == pdTRUE)? "Success" : "Failed");}/* 如果无法获得, 一直等待 */xStatus = xSemaphoreTakeRecursive(xMutex, portMAX_DELAY);printf("Task2: and then, take the Mutex %s\r\n", \(xStatus == pdTRUE)? "Success" : "Failed");/* 无限循环 */for( ;; ){ /* 什么都不做 */vTaskDelay(xTicksToWait);}
}
/*-----------------------------------------------------------*/
结果