第4章第6節 任務自結束

2021-08-03 05:35:02 字數 3330 閱讀 4154

目前更新到5.3節,請在

上節增加了刪除任務的函式mds_taskdelete

,任務可以呼叫該函式結束其它任務或自身任務的執行。在前面章節我們說過,目前任務還不具備自結束功能,需要使用類似

while

的結構迴圈執行。本節我們將增加任務自結束功能,在建立任務時不再受任何限制。

任務要做到自結束,需要解決2

個問題,一,任務需要能脫離作業系統的排程。二、任務在結束後,作業系統需要能發生排程,切換到下個任務繼續執行。

這2個問題我們都可以像上節那樣,呼叫

mds_taskdelete

函式解決,但如果使用

mds_taskdelete

函式來實現任務的自結束,那麼

mds_taskdelete

函式就必須以顯式的方式寫在每個任務主函式的最後一行,當任務執行到結束時,任務會執行

mds_taskdelete

函式結束自身的執行。這樣做有乙個明顯的缺點,我們需要為每個任務增加這樣一行**,不但對使用者進行了約束,使用不方便,而且如果使用者忘記了增加這行**,那麼作業系統執行到任務結束後就會崩潰掉。

前面我們介紹過,lr

暫存器中儲存的是本函式返回上級父函式的

pc指標,返回父函式時只要跳轉到該

pc指標就可以了。如果我們要做到任務自刪除,那麼就可以借用這個功能,可以將

mds_taskdelete

函式認為是每個建立任務所使用的主函式的父函式,在任務初始化時,將

mds_taskdelete

函式的位址賦給

lr暫存器,這樣當任務執行完最後一條指令時,它就會取出

lr暫存器中的

mds_taskdelete

函式的位址,跳轉到

mds_taskdelete

函式,實現任務的自結束功能。這種方式是隱式的,不會對使用者做任何限制,只需要我們修改

mds_taskstackinit

函式**,增加對

lr暫存器的初始化就可以一勞永逸了。

00011

void mds_taskstackinit(m_tcb* pstrtcb, vfunc vffuncpointer)

00012

mds_taskstackinit函式的改動量非常小,只需要在

33行將

mds_taskselfdelete

函式賦給

lr暫存器。

mds_taskselfdelete

函式封裝了

mds_taskdelete

函式,將存放當前指標的全域性變數

gpstrcurtcb

傳給mds_taskdelete

函式,完成任務的自刪除。

00191

void mds_taskselfdelete(void)

00192

本節的改動已經介紹完畢,本節的驗證函式與上節非常相似,其中test_testtask1

和test_testtask2

函式與上節完全一樣,

test_testtask3

函式修改為只迴圈

6次,每次迴圈時間為

1000 ticks

。由於test_testtask3

函式具有最高優先順序,並且在開始時

delay

了2000 ticks

,因此它會在

8000 ticks

時執行完畢,按照本節的設計,在

8000 ticks

時它應該會自結束執行,由任務刪除鉤子函式列印出任務刪除的資訊。

00053

void test_testtask3(void)

00054

00067}

除此之外root

任務也不需要再呼叫

mds_taskdelete

函式自我刪除,也是由本節新增加的隱式刪除方式進行自刪除。

00014

void mds_roottask(void)

00015

本節執行結果截圖如下:

圖 50

任務自刪除的列印資訊

讀者可以訪問

可以看到本節實際執行列印出的結果與我們上節的實際執行列印出的結果是一致的,這也是與我們設計相符的,但這裡還是有一點稍微的不同,見圖51

:圖 51

任務被刪除與自刪除的列印資訊對比

圖51左邊是上節列印輸出的資料,右邊是本節列印輸出的資料,這兩組資料對比的結果如圖

51所示,只有90和

92行的結果不同。上節當系統執行到

8000 ticks

時,root

任務delay

時間耗盡,恢復到

running

狀態,刪除了

test_testtask3

任務,之後又重新進入

delay

狀態,將

cpu控制權讓給了

test_testtask2

任務。而本節

test_testtask3

任務先是

delay

了2000

個ticks

,然後執行了6次

for迴圈,6次

for迴圈後,系統時間為

8000 ticks

,test_testtask3

任務執行結束,自己結束了執行,將

cpu控制權讓給了

test_testtask2

任務,因此本節刪除

test_testtask3

任務的操作是在

test_testtask3

任務中完成的,只有這點與上節在

root

任務中刪除

test_testtask3

任務是不同的。

圖51的截圖是

beyond compare

工具軟體的截圖,

beyond compare是一

款比較檔案和資料夾的工具

,它可以

比較出不同

源**檔案之間的細微差別並標記出來,即使你在成千上萬行**中只修改了1

個字元,它也會發現並標記出來,這對於軟體的維護有著非常重要的意義。

使用工具軟體解析本節任務切換過程的資料,結果如下圖所示:

圖 52

4.6節任務切換過程圖

對比上節中任務切換過程的圖49

,可以明顯的看出在

8000 ticks

時,本節是切換到了

test_testtask3

任務,而上節是切換到了

root

任務。

第4章 第6節 基本包裝型別

boolean,number,string。每當讀取乙個基本型別值的時候,後台就會建立乙個對應的基本包裝型別的物件。1 建立string 型別的乙個例項 2 在例項上呼叫指定的方法 3 銷毀這個例項 說明 引用型別與基本包裝型別的主要區別就是物件的生存期。使用new建立的應用型別的例項,在執行流離開...

第6章第3節 Bellman Ford 解決負權邊

對所有的邊進行n 1次的鬆弛操作 檢測乙個圖是否有負權迴路 如果在n 1鬆弛之後最短路仍然會發生變化,則改圖必然存在負權迴路 在實際操作中,bellman ford演算法經常會在未達到n 1輪鬆弛前就已經計算出最短路,n 1其實是最大值 因此可以新增乙個變數check用來標記陣列dis在本輪鬆弛中是...

python 第6章節 字典

1.在pythonkhaki,字典是一系列鍵值對,每個分鍵都與乙個值相關聯,你可以使用鍵來訪問與之相關的值。與鍵相關聯的值可以是數字 字串或者字典。字典名 2.鍵和值之間用冒號分隔,而鍵和鍵之間用逗號分隔。3.訪問字典 字典名 鍵號 4.新增鍵值對 字典是一種動態結構,可隨時在其中新增鍵值對,要新增...