要想使用好RTOS,做出更加穩(wěn)定可靠的產(chǎn)品,必須非常清楚底層的調(diào)度原理。由于RTOS的實(shí)時(shí)性與可控性,所以只有了解了其核心部分的設(shè)計(jì)思想,才能用起來得心應(yīng)手,游刃有余。本文從RT-Thread的調(diào)度器設(shè)計(jì)的運(yùn)行方式上解釋一下調(diào)度器的行為,從而更加深刻的理解RT-Thread操作系統(tǒng)的調(diào)度時(shí)機(jī)。
1.調(diào)度是什么?
調(diào)度一般就是合理的安排、協(xié)調(diào)資源,統(tǒng)一指揮去完成一件事,而在操作系統(tǒng)中,線程調(diào)度就是有多個(gè)就緒優(yōu)先級的任務(wù),找到最高優(yōu)先級任務(wù),交給CPU去運(yùn)行。

RT-Thread調(diào)度器就是起到判決線程當(dāng)前的優(yōu)先級,然后選擇當(dāng)前系統(tǒng)中最高優(yōu)先級的就緒態(tài)的線程交給CPU去管理。
調(diào)度又可以細(xì)分為兩種。可打斷調(diào)度:關(guān)鍵防止優(yōu)先級倒置;不可打斷調(diào)度:先來先服務(wù),不可中斷。RT-Thread 屬于實(shí)時(shí)操作系統(tǒng),所以其調(diào)度器實(shí)現(xiàn)的是可打斷的調(diào)度,當(dāng)有更高優(yōu)先級的線程或者更重要的任務(wù)就行,則可以打斷當(dāng)前任務(wù)的執(zhí)行狀態(tài),去執(zhí)行優(yōu)先級更高的任務(wù)。那么此時(shí),調(diào)度的時(shí)機(jī)就非常的關(guān)鍵了。
2.調(diào)度怎么實(shí)現(xiàn)?
RT-Thread在創(chuàng)建任務(wù)的時(shí)候,會指定任務(wù)的優(yōu)先級,一般來說,每個(gè)任務(wù)都有自己特定的唯一的優(yōu)先級。所以內(nèi)核線程對象中有不同的優(yōu)先級的任務(wù)列表。

如果最大指定為32個(gè)優(yōu)先級,那么可以用32位數(shù)據(jù)類型表示,每一個(gè)bit表示一個(gè)優(yōu)先級就緒的狀態(tài)。使用位圖的優(yōu)點(diǎn)就是速度快,而且內(nèi)存占用小。
一般來說,調(diào)度去找到最高優(yōu)先級的任務(wù)時(shí),就需要去做判斷。如何去找到最高優(yōu)先級的任務(wù)。一般來說,有兩種辦法:
軟件計(jì)算
硬件計(jì)算
這兩種的差別僅僅在于計(jì)算效率的問題,本質(zhì)目的并無差別。
而用軟件計(jì)算方法尋找最高優(yōu)先級有兩種實(shí)現(xiàn)的策略:
1.遍歷就緒的隊(duì)列,找到最小的優(yōu)先級就緒的隊(duì)列,尋找的時(shí)間不確定,時(shí)間復(fù)雜度O(n)。
2.采用空間換時(shí)間的辦法,事先做好一個(gè)bitmap
例如系統(tǒng)中最大有8個(gè)優(yōu)先級,那么bitmap如下:
1constrt_uint8_t__lowest_bit_bitmap[]=
2{
3/*00*/0,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
4/*10*/4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
5/*20*/5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
6/*30*/4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
7/*40*/6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
8/*50*/4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
9/*60*/5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
10/*70*/4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
11/*80*/7,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
12/*90*/4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
13/*A0*/5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
14/*B0*/4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
15/*C0*/6,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
16/*D0*/4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
17/*E0*/5,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0,
18/*F0*/4,0,1,0,2,0,1,0,3,0,1,0,2,0,1,0
19};
一般每一位代表一個(gè)就緒的狀態(tài),所以__rt_ffs程序的設(shè)計(jì)如下
1int__rt_ffs(intvalue)
2{
3if(value==0)return0;
4
5if(value&0xff)
6return__lowest_bit_bitmap[value&0xff]+1;
7
8if(value&0xff00)
9return__lowest_bit_bitmap[(value&0xff00)>>8]+9;
10
11if(value&0xff0000)
12return__lowest_bit_bitmap[(value&0xff0000)>>16]+17;
13
14return__lowest_bit_bitmap[(value&0xff000000)>>24]+25;
15}
如果當(dāng)前系統(tǒng)的線程狀態(tài)為0b0110 0000,那么轉(zhuǎn)換成十六進(jìn)制就是0x60,根據(jù)表中的狀態(tài)此時(shí)的最高優(yōu)先級是5+1=6。所以可以得出系統(tǒng)的優(yōu)先級,此時(shí)計(jì)算的復(fù)雜度為O(1)。
雖然RT-Thread 是支持同等優(yōu)先級的,但是在具體的業(yè)務(wù)邏輯的設(shè)計(jì)中,在使用RTOS常用的設(shè)計(jì)方法中,一般都是要求程序的運(yùn)行邏輯是可預(yù)測的,就是在程序執(zhí)行的過程中,可以預(yù)測到程序下一步的動作。所以rtos中同等優(yōu)先級,按照時(shí)間片輪訓(xùn)的這種方式設(shè)計(jì)業(yè)務(wù)邏輯的情況并不多。使用相同優(yōu)先級會增加系統(tǒng)的業(yè)務(wù)邏輯的復(fù)雜性。
3.什么時(shí)候系統(tǒng)做調(diào)度?
RT-Thread 是搶占式的系統(tǒng)調(diào)用,所以系統(tǒng)什么時(shí)候去做的調(diào)度非常的關(guān)鍵。系統(tǒng)調(diào)度行為具體又分為主動調(diào)度和被動調(diào)度兩種。
3.1 任務(wù)主動block
當(dāng)A線程在正常運(yùn)行時(shí),主動放棄CPU的使用權(quán),比如去執(zhí)行rt_thread_delay或者等待一個(gè)IPC消息時(shí),當(dāng)前線程會主動放棄CPU資源,此時(shí)去系統(tǒng)中尋找已經(jīng)就緒的最高優(yōu)先級的線程進(jìn)行調(diào)度。

這種方式應(yīng)用的場景比較豐富,比如當(dāng)前線程沒有獲取到資源時(shí),需讓出CPU的使用權(quán),或者事情做完了,主動讓出CPU的使用權(quán),這就是系統(tǒng)做調(diào)度的時(shí)機(jī)。
A線程的優(yōu)先級要高于B線程的優(yōu)先級,所以在A放棄CPU使用權(quán)后,已經(jīng)就緒的最高優(yōu)先級線程B就開始執(zhí)行了。
3.2 被更高優(yōu)先級的任務(wù)喚醒
這種方式就是當(dāng)比當(dāng)前運(yùn)行線程的優(yōu)先級高的線程處于就緒態(tài)時(shí),高優(yōu)先級的就緒態(tài)線程會被喚醒,低優(yōu)先級線程將暫停運(yùn)行,此時(shí)會調(diào)度到比當(dāng)前線程更高的優(yōu)先級線程中去。

按照理解A線程是正在運(yùn)行的線程,此時(shí)更高任務(wù)優(yōu)先級的線程C就緒處于就緒狀態(tài)了。比如創(chuàng)建了一個(gè)比A優(yōu)先級更高的C進(jìn)程,并startup C線程,此時(shí)會執(zhí)行rt_schedule()將線程切換到優(yōu)先級更高的C線程。此時(shí)A線程運(yùn)行狀態(tài)以及處理器寄存器狀態(tài)壓棧,更高優(yōu)先級的C線程的狀態(tài)以及處理器寄存器狀態(tài)出棧,并且開始運(yùn)行C線程。
3.3 yield放棄cpu使用
首先理解一下什么是yield,解釋成讓出,放棄比較合理。該出讓只針對于同等優(yōu)先級的線程。

這種情況只適用于A線程的優(yōu)先級等于B線程的優(yōu)先級的情況。因?yàn)镽TT支持同等優(yōu)先級的方式創(chuàng)建線程,相同的優(yōu)先級的切換是靠時(shí)間片輪詢來進(jìn)行的。所以,當(dāng)A線程正常運(yùn)行的時(shí)候,如果執(zhí)行了yield函數(shù),那么只相當(dāng)于將A線程的時(shí)間片消耗完,此時(shí)同等優(yōu)先級的D線程開始運(yùn)行。 由于在RTOS中,需要的是完成任務(wù)的確定性與可靠性,同等優(yōu)先級的情況比較有限,所以這一塊應(yīng)用的不多。
3.4 中斷中執(zhí)行調(diào)度
以上的三種屬于主動進(jìn)行調(diào)度的過程,其系統(tǒng)的執(zhí)行流程都是可以預(yù)測的,但是中斷去執(zhí)行調(diào)度卻是比較特殊。是被動調(diào)度。

這種方式是在中斷中執(zhí)行調(diào)度的,當(dāng)A線程正常運(yùn)行時(shí),此時(shí)來了一個(gè)中斷,由于中斷的優(yōu)先級是高于線程的。所以,中斷處理事情,如果在中斷中執(zhí)行了調(diào)度函數(shù),那么在中斷退出后,將直接切換到當(dāng)前系統(tǒng)中更高優(yōu)先級的線程去運(yùn)行。如果如果當(dāng)前系統(tǒng)的最高優(yōu)先級還是A,那么中斷退出后,執(zhí)行的最高優(yōu)先級線程依然是A。若存在線程E線程優(yōu)先級高于A并且處于就緒狀態(tài),此時(shí),中斷退出后,切換到E線程去執(zhí)行。
4.調(diào)度做了哪些事情?
系統(tǒng)進(jìn)行調(diào)度的時(shí)候做了哪些事情?
第一步:查找當(dāng)前系統(tǒng)中當(dāng)前以及就緒的最高優(yōu)先級的線程,若有高于當(dāng)前運(yùn)行系統(tǒng)運(yùn)行的線程棧則執(zhí)行線程切換
第二步:關(guān)閉中斷,將系統(tǒng)當(dāng)前運(yùn)行狀態(tài)以及處理器的寄存器壓入棧空間
第三步:找到需要運(yùn)行的線程的PC指針,并找到棧起始處彈出棧空間中的寄存器狀態(tài)
第四部:打開中斷,執(zhí)行異常ret,讓系統(tǒng)恢復(fù)執(zhí)行
此時(shí),就切換到已經(jīng)就緒的更高優(yōu)先級的線程去運(yùn)行了。
5.總結(jié)
RT-Thread 線程的調(diào)度器是整個(gè)系統(tǒng)的靈魂,整個(gè)操作系統(tǒng)在運(yùn)行過程中何時(shí)切換線程、什么情況下去處理任務(wù),以及做更高效的業(yè)務(wù)邏輯的應(yīng)用都離不開系統(tǒng)調(diào)度。掌握了調(diào)度器運(yùn)行的規(guī)律,并且合理的使用線程調(diào)度時(shí)機(jī),可以設(shè)計(jì)出更加穩(wěn)定可靠的產(chǎn)品。通過閱讀代碼,就能預(yù)測程序下一步的執(zhí)行動作。真正的做到手中有糧,心中不慌。
-
cpu
+關(guān)注
關(guān)注
68文章
11277瀏覽量
224938 -
操作系統(tǒng)
+關(guān)注
關(guān)注
37文章
7401瀏覽量
129278 -
實(shí)時(shí)操作系統(tǒng)
+關(guān)注
關(guān)注
1文章
206瀏覽量
31946 -
RT-Thread
+關(guān)注
關(guān)注
32文章
1613瀏覽量
44819 -
調(diào)度器
+關(guān)注
關(guān)注
0文章
99瀏覽量
5683
原文標(biāo)題:?RT-Thread的線程調(diào)度與管理分析
文章出處:【微信號:RTThread,微信公眾號:RTThread物聯(lián)網(wǎng)操作系統(tǒng)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
硬實(shí)時(shí)·廣生態(tài)·強(qiáng)賦能,中國工業(yè)報(bào)解讀RT-Thread工業(yè)發(fā)展之路|新聞資訊
【好書推薦】RT-Thread第22本相關(guān)書籍!《嵌入式實(shí)時(shí)操作系統(tǒng)開發(fā)實(shí)踐》| 技術(shù)集結(jié)
RT-Thread睿賽德榮獲工博會“CIIF信息技術(shù)獎”,“1+X+N”戰(zhàn)略推動國產(chǎn)操作系統(tǒng)體系化發(fā)展 | 新聞速遞
學(xué)習(xí)強(qiáng)國深度報(bào)道 RT-Thread“1+X+N”戰(zhàn)略,國產(chǎn)操作系統(tǒng)賦能高端制造引關(guān)注|媒體視角
【好書推薦】RT-Thread第20本相關(guān)書籍!《嵌入式實(shí)時(shí)操作系統(tǒng)RT-Thread原理與應(yīng)用》| 技術(shù)集結(jié)
經(jīng)濟(jì)日報(bào):國產(chǎn)嵌入式操作系統(tǒng)領(lǐng)軍企業(yè)RT-Thread正在持續(xù)把新思想、新技術(shù)留給上海|媒體視角
RT-Thread 遇上 Rust:安全內(nèi)核 RusT-Thread 的誕生
權(quán)威認(rèn)證!RT-Thread操作系統(tǒng)100%國產(chǎn)自主可控,鑄就睿擎工業(yè)平臺安全基石? !
RT-Thread榮獲2025優(yōu)秀開源項(xiàng)目 | 新聞速遞
深度剖析 RT-Thread 線程調(diào)度流程
玄鐵加入RT-Thread 高級會員合作伙伴 | 戰(zhàn)略新篇
2025 RT-Thread全球技術(shù)大會議程正式發(fā)布!
【直播預(yù)告】《實(shí)時(shí)操作系統(tǒng)應(yīng)用技術(shù)—基于RT-Thread與ARM的編程實(shí)踐》教學(xué)脈絡(luò)及資源簡介
RT-Thread審核團(tuán)招募: 深度參與開源RTOS社區(qū)治理與演進(jìn)
RT-Thread嵌入式操作系統(tǒng)專業(yè)培訓(xùn)班-深圳站重磅開啟!
RT-Thread操作系統(tǒng)的調(diào)度設(shè)計(jì)原理
評論