在基于RTOS開發(fā)項(xiàng)目時(shí),通常都會(huì)遇到互斥的情況,比如:幾個(gè)任務(wù)都要使用一個(gè)UART串口進(jìn)行發(fā)送數(shù)據(jù)。
如果不加互斥鎖,優(yōu)先級(jí)高的任務(wù),會(huì)搶占串口并發(fā)送數(shù)據(jù),則有可能會(huì)出現(xiàn)發(fā)送數(shù)據(jù)“亂碼”的情況。
今天就說(shuō)說(shuō)在RTOS開發(fā)中,互斥鎖一個(gè)常見的問(wèn)題。
什么是Mutex互斥鎖?
學(xué)習(xí)過(guò)RTOS的讀者應(yīng)該對(duì)互斥不陌生,互斥鎖就是為了避免任務(wù)之間互相搶占某種資源而設(shè)計(jì)的一種“鎖”。
就如上面說(shuō)的,一個(gè)串口,被兩個(gè)任務(wù)搶占,如果不加鎖,則會(huì)出現(xiàn)兩個(gè)任務(wù)交叉發(fā)送數(shù)據(jù),即“亂碼”;
但是,如果加了互斥鎖,則會(huì)等待其他任務(wù)發(fā)送完成之后才繼續(xù)發(fā)送,保證了數(shù)據(jù)的完整(而不是亂碼);
嵌入式專欄
2
Mutex互斥鎖例子
這里以三個(gè)任務(wù)、兩個(gè)互斥鎖為例,代碼如下:
void task1(){ /*do something*/ OSMutex1_Pend(); //互斥鎖1加鎖 /*加鎖處理事情*/ OSMutex1_Post(); //互斥鎖1解鎖} void task2(){ /*do something*/ OSMutex1_Pend(); //互斥鎖1加鎖 OSMutex2_Pend(); //互斥鎖2加鎖 /*加鎖處理事情*/ OSMutex2_Post(); //互斥鎖2解鎖 OSMutex1_Post(); //互斥鎖1解鎖} void task3(){ /*do something*/ OSMutex2_Pend(); //互斥鎖2加鎖/*加鎖處理事情*/ OSMutex2_Post(); //互斥鎖1解鎖}
這樣設(shè)計(jì),大家看出問(wèn)題了嗎?
老司機(jī)應(yīng)該看出來(lái)了,新手可能摸不著頭腦。
在任務(wù)2中,進(jìn)行了2次加鎖、解鎖,而且“環(huán)環(huán)相扣”。
Mutex互斥鎖問(wèn)題
假如任務(wù)1、 任務(wù)2、任務(wù)3優(yōu)先級(jí)分別為:1、 2、 3。
優(yōu)先級(jí)順序就是:任務(wù)1 >任務(wù)2>任務(wù)3(數(shù)字越小代表任務(wù)優(yōu)先級(jí)越高)。
假設(shè):任務(wù)1和任務(wù)2處于等待事件狀態(tài),也就是處于阻塞狀態(tài), task 3 處于運(yùn)行狀態(tài)。
當(dāng)任務(wù)3在“加鎖處理事情”的時(shí)候,任務(wù)2搶占了任務(wù)3(任務(wù)2掛起時(shí)間到了),此時(shí)任務(wù)3掛起,任務(wù)2處于運(yùn)行狀態(tài);
如果任務(wù)2在“互斥鎖1加鎖”之后,任務(wù)1搶占了任務(wù)2,此時(shí),任務(wù)1處于運(yùn)行狀態(tài);
這個(gè)時(shí)候,你發(fā)現(xiàn)問(wèn)題了沒有?
任務(wù)1在執(zhí)行“OSMutex1_Pend();”會(huì)等待“互斥鎖1解鎖”,如果其他方式?jīng)]有對(duì)“互斥鎖1解鎖”,則會(huì)出現(xiàn)“死鎖”的情況。
分享一張圖片,你就會(huì)明白什么是死鎖了:
解決辦法
比如對(duì)任務(wù)2加鎖方式進(jìn)行改善:
void task2(){ /*do something*/ OSMutex1_Pend(); //互斥鎖1加鎖 /*do something*/ OSMutex1_Post(); //互斥鎖1解鎖 OSMutex2_Pend(); //互斥鎖2加鎖 /*do something*/ OSMutex2_Post(); //互斥鎖1解鎖}
或者對(duì)低優(yōu)先級(jí)的任務(wù)3加鎖方式進(jìn)行改善:
void task3(){ /*do something*/ OSMutex1_Pend(); //互斥鎖1加鎖 OSMutex2_Pend(); //互斥鎖2加鎖 /*加鎖處理事情*/ OSMutex2_Post(); //互斥鎖2解鎖 OSMutex1_Post(); //互斥鎖1解鎖}
出問(wèn)題的原因, 當(dāng)一個(gè)任務(wù)獲得了臨界區(qū)資源的鎖,在沒有釋放這個(gè)鎖的前提下又去獲得另外一塊臨界區(qū)資源,這個(gè)時(shí)候就要引起足夠的注意了,設(shè)計(jì)成敗在于你是否徹底理解了之前的問(wèn)題。 但是,歸根到底這樣的問(wèn)題還是要求用戶在設(shè)計(jì)階段去避免,一個(gè)系統(tǒng)不可能是萬(wàn)能的,正確的設(shè)計(jì)才是最重要的。
-
數(shù)據(jù)
+關(guān)注
關(guān)注
8文章
7077瀏覽量
89161 -
RTOS
+關(guān)注
關(guān)注
22文章
817瀏覽量
119714 -
Uart串口
+關(guān)注
關(guān)注
0文章
29瀏覽量
6830
原文標(biāo)題:RTOS 任務(wù)間互斥的問(wèn)題
文章出處:【微信號(hào):strongerHuang,微信公眾號(hào):strongerHuang】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論