临界区问题的产生
臨界區(qū)問題是嵌入式軟件編程一個不得不面對的關鍵性問題。特別對于底層驅動,代碼在內存中只有一份,上層的多任務或者多進程,都會對同一個驅動去訪問,這樣不可避免的遇到了任務之間打架的問題,處理好這個問題是區(qū)分一個菜鳥和老鳥的根本性關鍵之一。
接下來談談臨界區(qū)產生的原因:
假設有以下代碼:
[cpp]?view plaincopy
假如在一個可以搶占的操作系統(tǒng)上有兩個任務task1, task2, 全局變量x 的初始值為0, 現(xiàn)在兩個任務task1, task2 同時去訪問process_data 這個函數,兩個任務各執(zhí)行一次process_data 這個函數,等到兩個人執(zhí)行完畢后,試問x的值是多少?大部分人可能會回答為2。沒有操作系統(tǒng)的時候,的卻不錯,調用函數2次,就是2.問題是有了操作系統(tǒng)就沒這么簡單了,一個任務執(zhí)行期間,隨時可能會被另外一個任務給打斷,這樣就會造成臨界區(qū)的問題。
?
首先明確一個基本概念,在操作系統(tǒng)中每一個任務都有自己的一套寄存器,各個任務間的寄存器值很可能是不一樣的。
?
下面來具體分析這個問題產生的根本原因:
x++ 不是一個原子型的操作,它的匯編函數有3句,分別是:
1 ldr r1, [mem]
2 add r1, r1, #1
3 str r1 [mem]
假如任務task1 剛執(zhí)行完2即 add r1, r1,#1,因為是可以搶占的操作系統(tǒng),所以被任務task 2 給搶占了,然后task 2 執(zhí)行完1,2,3 這三個步驟后還給任務task 1.
如前所述,圖中的task1 和task2 的寄存器值是不同的,因為任務各自有自己的一套寄存器。讀者可以推導一下,x 的最終值是1而不是2!
?
所以在多任務的情況下,共同去訪問一個全局變量,會產生臨界區(qū)的問題,如之前所述最終值可能是不確定的,可能是1也可能是2,所以需要采用操作系統(tǒng)的一定機制去保護它。
總結
- 上一篇: 前后台系统的精髓
- 下一篇: STM32通过USB实现Bootlade