找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

帖子
查看: 8834|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

uC/OS-II學(xué)習(xí)筆記—任務(wù)的刪除

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:51773 發(fā)表于 2013-7-18 20:04 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
任務(wù)狀態(tài)轉(zhuǎn)換圖如下所示:

一開始,任務(wù)在操作系統(tǒng)中是以函數(shù)代碼的形式存在的,在操作系統(tǒng)啟動(dòng)的時(shí)候被加載到內(nèi)存中,并未運(yùn)行。并且,最開始的時(shí)候就緒表和就緒組是空的,或者說里面的內(nèi)容都是0。很明顯,這時(shí)候任務(wù)在內(nèi)存中睡眠,處于睡眠態(tài)。 如果不調(diào)用任務(wù)創(chuàng)建函數(shù)對(duì)任務(wù)進(jìn)行操作,該任務(wù)將永遠(yuǎn)處于睡眠態(tài)直到操作系統(tǒng)結(jié)束運(yùn)行,被清除出內(nèi)存。
任務(wù)的創(chuàng)建的學(xué)習(xí)中可以看到,任務(wù)創(chuàng)建的過程,首先分配一個(gè)空閑的TCB給任務(wù),然后對(duì)該TCB的各個(gè)域進(jìn)行賦值,對(duì)任務(wù)的堆棧進(jìn)行初始化,其中,任務(wù)的代碼的地址被壓入堆棧。這為以后任務(wù)的運(yùn)行做了充分的準(zhǔn)備。就緒表和就緒組做了適當(dāng)?shù)奶幚恚鶕?jù)任務(wù)的優(yōu)先級(jí)進(jìn)行了設(shè)置。就緒TCB鏈表也插入了該TCB。
那么,若將任務(wù)刪除,如上圖所示,很明顯是任務(wù)的逆過程,應(yīng)該將就緒表、就緒組進(jìn)行逆向的操作,就緒鏈表中的相關(guān)TCB應(yīng)該被移除,轉(zhuǎn)移到空閑TCB鏈表。和任務(wù)創(chuàng)建一,也要進(jìn)行一些檢查,看任務(wù)是否符合被刪除的條件。
任務(wù)刪除還涉及一個(gè)請(qǐng)求刪除的問題,因此任務(wù)刪除看似簡單,實(shí)際上是比較復(fù)雜的一個(gè)過程。
任務(wù)刪除函數(shù)的參數(shù)只有一個(gè),這個(gè)參數(shù)就是任務(wù)的優(yōu)先級(jí)。 我們知道,任務(wù)的優(yōu)先級(jí)是uC/OS-II標(biāo)志任務(wù)的唯一標(biāo)志,任務(wù)控制塊中雖然也有一個(gè)ID,但只是為了擴(kuò)展使用。因此,任務(wù)刪除函數(shù)也可以理解為刪除指定優(yōu)先級(jí)的任務(wù)。程序代碼如下所示:


從任務(wù)刪除的代碼中可以看到,任務(wù)刪除遠(yuǎn)遠(yuǎn)不像想象中那么簡單。刪除一個(gè)任務(wù),就要照顧到該任務(wù)已經(jīng)影響到的方方面面,否則系統(tǒng)就可能崩潰。由于任務(wù)刪除的代碼很長,而在執(zhí)行的過程中一直在訪問全局變量,因此使系統(tǒng)不能響應(yīng)中斷,破壞系統(tǒng)實(shí)時(shí)性。因此,在代碼的中間,使用巧妙的手段開一次中斷,過程如下:
(1)將任務(wù)調(diào)度鎖加1。
(2)開中斷
(3)執(zhí)行一條空語句保證中斷有時(shí)間執(zhí)行。
(4)關(guān)中斷
(5)將調(diào)度鎖減1,恢復(fù)原來的值。
刪除任務(wù)的代碼盡管復(fù)雜,但無外乎先進(jìn)行參數(shù)的檢查,然后如果該任務(wù)在等待某些事件,就刪除等待的標(biāo)志,之后對(duì)TCB中的值進(jìn)行修改,對(duì)就緒表、就緒組、任務(wù)優(yōu)先級(jí)指針表、就緒任務(wù)鏈表、空閑任務(wù)鏈表等重要的數(shù)據(jù)結(jié)構(gòu)進(jìn)行與創(chuàng)建任務(wù)相反的操作,只不過中間因?yàn)榇a執(zhí)行時(shí)間過長,增加了臨時(shí)允許中斷的操作。

關(guān)于任務(wù)的刪除,除了這個(gè)直接刪除任務(wù)的函數(shù)之外,還有一個(gè)非常重要的請(qǐng)求刪除任務(wù)的函數(shù)——OSTaskDelReq。
當(dāng)以其他任務(wù)的優(yōu)先級(jí)作為參數(shù)的時(shí)候,OSTaskDel粗暴地刪除了任務(wù),這在某些情況下是有效的,但是卻不是必須這樣做。通知對(duì)方任務(wù),告訴它要?jiǎng)h除你了,請(qǐng)任務(wù)自己刪除自己是一種更好的做法。因?yàn)檫@么做,任務(wù)可以在刪除自己之前先放棄自己使用的資源,如緩沖區(qū)、信號(hào)量、郵箱、隊(duì)列等。如果總是用OSTaskDel刪除一個(gè)任務(wù),這個(gè)任務(wù)占用的資源不能得到釋放,系統(tǒng)就會(huì)產(chǎn)生內(nèi)存泄漏,在內(nèi)存泄漏累積到較大的時(shí)候,系統(tǒng)就會(huì)最后因?yàn)闆]有可用的內(nèi)存崩潰。
其實(shí),OSTaskDelReq名稱雖然是請(qǐng)求,卻是集請(qǐng)求與響應(yīng)于一段代碼內(nèi),該代碼的功能是請(qǐng)求刪除某任務(wù)和查看自己是否有任務(wù)要?jiǎng)h除自己。
例如,優(yōu)先級(jí)為5的任務(wù)A調(diào)用OSTaskDelReq(10),請(qǐng)求刪除優(yōu)先級(jí)為10的任務(wù)B。任務(wù)B調(diào)用OSTaskDelReq(OS_PRIO_SEL)并查看返回值,如果返回值為OS_ERR_TASK_DEL_REQ,說明有任務(wù)要求刪除自己了。任務(wù)B應(yīng)該先釋放自己使用的資源,然后調(diào)用OSTaskDel(10)或OSTaskDel(OS_PRIO_SEL)來刪除自己。代碼如下所示:

可見,請(qǐng)求刪除任務(wù)的代碼是比較少的,且前面一段是參數(shù)的檢查。后半部分的代碼根據(jù)參數(shù)不同,分別執(zhí)行判斷是否有請(qǐng)求參數(shù)標(biāo)志和給對(duì)方任務(wù)打上請(qǐng)求刪除標(biāo)志。
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏2 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表