/* 创建一个递归锁,返回它的句柄。
* 此函数内部会分配互斥量结构体
* 返回值: 返回句柄,非NULL表示成功
*/
SemaphoreHandle_t xSemaphoreCreateRecursiveMutex( void );
/* 释放 */
BaseType_t xSemaphoreGiveRecursive( SemaphoreHandle_t xSemaphore );
/* 获得 */
BaseType_t xSemaphoreTakeRecursive(
SemaphoreHandle_t xSemaphore,
TickType_t xTicksToWait
);
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);
}
}
?main函数:
SemaphoreHandle_t xMutex;
int main( void )
{
prvSetupHardware();
/* 创建递归锁 */
xMutex = xSemaphoreCreateRecursiveMutex( );
if( xMutex != NULL )
{
/* 创建2个任务: 一个上锁, 另一个自己监守自盗(开别人的锁自己用)
*/
xTaskCreate( vTakeTask, "Task1", 1000, NULL, 2, NULL );
xTaskCreate( vGiveAndTakeTask, "Task2", 1000, NULL, 1, NULL );
/* 启动调度器 */
vTaskStartScheduler();
}
else
{
/* 无法创建递归锁 */
}
/* 如果程序运行到了这里就表示出错了, 一般是内存不足 */
return 0;
}
A:任务1优先级最高,先运行,获得递归锁
B:任务1阻塞,让任务2得以运行
C:任务2运行,看看能否获得别人持有的递归锁:不能
D:任务2故意执行"give"操作,看看能否释放别人持有的递归锁:不能
E:任务2等待递归锁
F:任务1阻塞时间到后继续运行,使用循环多次获得、释放递归锁
递归锁在代码上实现了:谁持有递归锁,必须由谁释放。
?