欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語言 Freertos的遞歸鎖詳解

 更新時(shí)間:2022年03月10日 10:24:31   作者:小陽先生的寶庫  
這篇文章主要為大家詳細(xì)介紹了C語言的遞歸鎖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助

1.死鎖的概念

假設(shè)有 2 個(gè)互斥量 M1、 M2, 2 個(gè)任務(wù) A、 B:
A 獲得了互斥量 M1
B 獲得了互斥量 M2
A 還要獲得互斥量 M2 才能運(yùn)行,結(jié)果 A 阻塞
B 還要獲得互斥量 M1 才能運(yùn)行,結(jié)果 B 阻塞
A、 B 都阻塞,再無法釋放它們持有的互斥量
死鎖發(fā)生!

在這里插入圖片描述

2.自我死鎖

任務(wù) A 獲得了互斥鎖 M
它調(diào)用一個(gè)函數(shù)
函數(shù)要去獲取同一個(gè)互斥鎖 M,于是它阻塞:任務(wù) A 休眠,等待任務(wù) A
來釋放互斥鎖!
死鎖發(fā)生!

在這里插入圖片描述

3.遞歸鎖

1.任務(wù) A 獲得遞歸鎖 M 后,它還可以多次去獲得這個(gè)鎖

2."take"了 N 次,要"give"N 次,這個(gè)鎖才會被釋放

3.誰上鎖就由誰解鎖。

遞歸鎖的函數(shù)根一般互斥量的函數(shù)名不一樣

 遞歸鎖一般互斥量
創(chuàng)建xSemaphoreCreateRecursiveMutexxSemaphoreCreateMutex
獲得xSemaphoreTakeRecursivexSemaphoreTake
釋放xSemaphoreGiveRecursivexSemaphoreGive

4.代碼

main

/* 遞歸鎖句柄 */
SemaphoreHandle_t xMutex;
int main( void )
{
	prvSetupHardware();
    /* 創(chuàng)建遞歸鎖 */
    xMutex = xSemaphoreCreateRecursiveMutex( );
	if( xMutex != NULL )
	{
		/* 創(chuàng)建2個(gè)任務(wù): 一個(gè)上鎖, 另一個(gè)自己監(jiān)守自盜(開別人的鎖自己用)
		xTaskCreate( vTakeTask, "Task1", 1000, NULL, 2, NULL );
		xTaskCreate( vGiveAndTakeTask, "Task2", 1000, NULL, 1, NULL );
		/* 啟動調(diào)度器 */
		vTaskStartScheduler();
	}
	else
	{
		/* 無法創(chuàng)建遞歸鎖 */
	}
	return 0;
}

任務(wù)1

static void vTakeTask( void *pvParameters )
{
	const TickType_t xTicksToWait = pdMS_TO_TICKS( 100UL );	
	BaseType_t xStatus;
	int i;
	
	/* 無限循環(huán) */
	for( ;; )
	{	
		/* 獲得遞歸鎖: 上鎖 */
		xStatus = xSemaphoreTakeRecursive(xMutex, portMAX_DELAY);
		printf("Task1 take the Mutex in main loop %s\r\n", \
			(xStatus == pdTRUE)? "Success" : "Failed");
		/* 阻塞很長時(shí)間, 讓另一個(gè)任務(wù)執(zhí)行, 
		 * 看看它有無辦法再次獲得遞歸鎖 
		 */
		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);
	}
}

任務(wù)2

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");
	/* 如果失敗則監(jiān)守自盜: 開鎖 */
	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");
	/* 無限循環(huán) */
	for( ;; )
	{	
		/* 什么都不做 */
		vTaskDelay(xTicksToWait);
	}
}

5.運(yùn)行流程分析

1.任務(wù) 1 優(yōu)先級最高,先運(yùn)行,獲得遞歸鎖

2.任務(wù) 1 阻塞,讓任務(wù) 2 得以運(yùn)行

3.任務(wù) 2 運(yùn)行,看看能否獲得別人持有的遞歸鎖: 不能

4.任務(wù) 2 故意執(zhí)行"give"操作,看看能否釋放別人持有的遞歸鎖:不能

5.任務(wù) 2 等待遞歸鎖

6.任務(wù) 1 阻塞時(shí)間到后繼續(xù)運(yùn)行,使用循環(huán)多次獲得、釋放遞歸鎖

6.運(yùn)行結(jié)果

在這里插入圖片描述

總結(jié)

誰持有遞歸鎖,必須由誰釋放。

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!    

相關(guān)文章

  • C語言實(shí)現(xiàn)宿舍管理系統(tǒng)

    C語言實(shí)現(xiàn)宿舍管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)宿舍管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • Qt6.0?qproperty-*不生效原因解決分析

    Qt6.0?qproperty-*不生效原因解決分析

    這篇文章主要為大家介紹了Qt6.0?qproperty-*不生效原因解決分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • 項(xiàng)目之C++如何實(shí)現(xiàn)數(shù)據(jù)庫連接池

    項(xiàng)目之C++如何實(shí)現(xiàn)數(shù)據(jù)庫連接池

    這篇文章主要介紹了項(xiàng)目之C++如何實(shí)現(xiàn)數(shù)據(jù)庫連接池問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • C++通過循環(huán)實(shí)現(xiàn)猜數(shù)字小游戲

    C++通過循環(huán)實(shí)現(xiàn)猜數(shù)字小游戲

    這篇文章主要為大家詳細(xì)介紹了C++通過循環(huán)實(shí)現(xiàn)猜數(shù)字小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-09-09
  • C語言 詳細(xì)講解邏輯運(yùn)算符的使用

    C語言 詳細(xì)講解邏輯運(yùn)算符的使用

    在C語言中,邏輯運(yùn)算符有&&、||、!;&&表示“與”的意思,需要兩端的表達(dá)式的值都為true,該式的值才為true。||表示“或”的意思,兩端的表達(dá)式的值只要有一端為true,該式的值就為true。!表示“非”的意思,將該式的真值換成相反的真值,即false和true互換
    2022-04-04
  • bloom filter概念講解以及代碼分析

    bloom filter概念講解以及代碼分析

    Bloom filter 優(yōu)點(diǎn)就是它的插入和查詢時(shí)間都是常數(shù),另外它查詢元素卻不保存元素本身,具有良好的安全性
    2013-09-09
  • C++中隊(duì)列queue的用法實(shí)例詳解

    C++中隊(duì)列queue的用法實(shí)例詳解

    隊(duì)列先進(jìn)先出,即只能在容器的末尾添加新元素,只能從頭部移除元素,下面這篇文章主要給大家介紹了關(guān)于C++中隊(duì)列queue用法的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-04-04
  • C++面向行輸入之get()與getline()實(shí)例詳解

    C++面向行輸入之get()與getline()實(shí)例詳解

    在c++里當(dāng)我們輸入一個(gè)字符串時(shí)習(xí)慣用cin,但是cin只能讀取一段不含空格的字符串,如果我們需要讀取一段包含空格的字符串時(shí),就需要用到getline()或get(),下面這篇文章主要給大家介紹了關(guān)于C++面向行輸入之get()與getline()的相關(guān)資料,需要的朋友可以參考下
    2021-10-10
  • c++版線程池和任務(wù)池示例

    c++版線程池和任務(wù)池示例

    這篇文章主要介紹了c++版線程池和任務(wù)池,實(shí)現(xiàn)任務(wù)執(zhí)行完畢線程退出.在linux下壓力測試通過
    2014-03-03
  • C++線程池的簡單實(shí)現(xiàn)方法

    C++線程池的簡單實(shí)現(xiàn)方法

    這篇文章主要介紹了C++線程池的簡單實(shí)現(xiàn)方法,包括了線程操作函數(shù)及相關(guān)屬性的用法,需要的朋友可以參考下
    2014-09-09

最新評論