同步与互斥(三)
2023-12-26 08:37:14
一、递归锁
/* 创建一个递归锁,返回它的句柄。
* 此函数内部会分配互斥量结构体
* 返回值: 返回句柄,非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);//任务一上锁了,任务二上锁失败
//0说明不会等,上锁失败直接返回
// xMutex = xSemaphoreCreateRecursiveMutex( );同一把锁
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");
}
printf("task2\r\n");
/* 如果无法获得, 一直等待 */
xStatus = xSemaphoreTakeRecursive(xMutex, portMAX_DELAY);//任务二一直堵在这,下不去了
//xStatus = xSemaphoreTakeRecursive(xMutex, 0);//改成0就能运行下去
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阻塞时间到后继续运行,使用循环多次获得、释放递归锁
递归锁在代码上实现了:谁持有递归锁,必须由谁释放。
文章来源:https://blog.csdn.net/weixin_57604904/article/details/135164330
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!