www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁(yè) > 公眾號(hào)精選 > 嵌入式IoT

rt-thread的線程調(diào)度與管理


  • ?1.調(diào)度是什么?

  • ?2.調(diào)度怎么實(shí)現(xiàn)?

  • ?3.什么時(shí)候系統(tǒng)做調(diào)度?

    • ?3.1 任務(wù)主動(dòng)block

    • ?3.2 被更高優(yōu)先級(jí)的任務(wù)喚醒

    • ?3.3 yield放棄cpu使用

    • ?3.4 中斷中執(zhí)行調(diào)度

  • ?4.調(diào)度做了哪些事情?

  • ?5.總結(jié)


要想使用好rtos,做出更加穩(wěn)定可靠的產(chǎn)品,必須非常清楚底層的調(diào)度原理。由于RTOS的可控性,所以只有了解了其核心部分的設(shè)計(jì)思路,才能用起來(lái)得心應(yīng)手,游刃有余。本文主要是聽(tīng)完熊大對(duì)rt-thread調(diào)度講解之后,自己做了一些反思總結(jié),打算分享一下rt-thread線程的調(diào)度與管理相關(guān)的比較核心和重要的部分的筆記。

1.調(diào)度是什么?

調(diào)度一般就是合理的安排,協(xié)調(diào)資源,統(tǒng)一指揮去完成一件事,而在操作系統(tǒng)中,線程調(diào)度就是有多個(gè)就緒優(yōu)先級(jí)的任務(wù),找到最高優(yōu)先級(jí)任務(wù),交給CPU去運(yùn)行。


rt-thread調(diào)度器就是起到判決線程當(dāng)前的優(yōu)先級(jí),然后去執(zhí)行當(dāng)前最高優(yōu)先級(jí)的就緒的線程。

調(diào)度又可以細(xì)分為兩種。可打斷調(diào)度:關(guān)鍵防止優(yōu)先級(jí)倒置 ;不可打斷調(diào)度:先來(lái)先服務(wù),不可中斷。

2.調(diào)度怎么實(shí)現(xiàn)?

在創(chuàng)建任務(wù)的時(shí)候,指定了任務(wù)的優(yōu)先級(jí),一般來(lái)說(shuō),每個(gè)任務(wù)都有自己特定的優(yōu)先級(jí)。所以內(nèi)核線程對(duì)象中有不同的優(yōu)先級(jí)的任務(wù)列表。

如果最大指定為32個(gè)優(yōu)先級(jí),那么可以用u32,每一個(gè)bit表示一個(gè)優(yōu)先級(jí)就緒的狀態(tài)。使用位圖的優(yōu)點(diǎn)就是速度快,而且內(nèi)存占用小。

一般來(lái)說(shuō),調(diào)度去找到最高優(yōu)先級(jí)的任務(wù)時(shí),就需要去做判斷。如何去找到最高優(yōu)先級(jí)的任務(wù)。一般來(lái)說(shuō),有兩種辦法:

  • 軟件計(jì)算
  • 硬件計(jì)算

這兩種的差別僅僅在于計(jì)算效率的問(wèn)題,本質(zhì)目的并無(wú)差別。

而尋找最高優(yōu)先級(jí)的事情也是有兩種實(shí)現(xiàn)的策略:

1.遍歷就緒的隊(duì)列,找到最小的就緒的隊(duì)列,尋找的時(shí)間不確定,時(shí)間復(fù)雜度O(n)。

2.采用空間換時(shí)間的辦法,事先做好一個(gè)bitmap

例如系統(tǒng)中最大有8個(gè)優(yōu)先級(jí),那么bitmap如下:

const rt_uint8_t __lowest_bit_bitmap[] =
{
 /* 00 */ 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
 /* 10 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
 /* 20 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
 /* 30 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
 /* 40 */ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
 /* 50 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
 /* 60 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
 /* 70 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
 /* 80 */ 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
 /* 90 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
 /* A0 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
 /* B0 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
 /* C0 */ 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
 /* D0 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
 /* E0 */ 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0,
 /* F0 */ 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
};

一般每一位代表一個(gè)就緒的狀態(tài),所以__rt_ffs程序的設(shè)計(jì)如下

int __rt_ffs(int value)
{ if (value == 0) return 0; if (value & 0xff) return __lowest_bit_bitmap[value & 0xff] + 1; if (value & 0xff00) return __lowest_bit_bitmap[(value & 0xff00) >> 8] + 9; if (value & 0xff0000) return __lowest_bit_bitmap[(value & 0xff0000) >> 16] + 17; return __lowest_bit_bitmap[(value & 0xff000000) >> 24] + 25;
}

如果當(dāng)前系統(tǒng)的線程狀態(tài)為0b0110 0000,那么轉(zhuǎn)換成十六進(jìn)制就是0x60,根據(jù)表中的狀態(tài)此時(shí)的最高優(yōu)先級(jí)是5+1=6。所以可以得出系統(tǒng)的優(yōu)先級(jí),此時(shí)計(jì)算的復(fù)雜度為O(1)。

雖然rtt是支持同等優(yōu)先級(jí)的,但是在具體的業(yè)務(wù)邏輯的設(shè)計(jì)中,在使用RTOS常用的設(shè)計(jì)方法中,一般都是要求程序的運(yùn)行邏輯是可預(yù)測(cè)的,就是在程序執(zhí)行的過(guò)程中,可以預(yù)測(cè)到程序下一步的動(dòng)作。所以rtos中同等優(yōu)先級(jí),按照時(shí)間片輪訓(xùn)的這種方式設(shè)計(jì)業(yè)務(wù)邏輯的情況并不多。使用相同優(yōu)先級(jí)會(huì)增加系統(tǒng)的業(yè)務(wù)邏輯的復(fù)雜性。

3.什么時(shí)候系統(tǒng)做調(diào)度?

RTT是搶占式的系統(tǒng)調(diào)用,所以系統(tǒng)什么時(shí)候去做的調(diào)度非常的關(guān)鍵。系統(tǒng)調(diào)度分為主動(dòng)調(diào)度和被動(dòng)兩種。

3.1 任務(wù)主動(dòng)block

當(dāng)A線程在正常運(yùn)行時(shí),主動(dòng)放棄CPU的使用權(quán),比如去執(zhí)行rt_thread_delay或者去等待一個(gè)IPC的事件到來(lái)時(shí),都會(huì)釋放CPU進(jìn)行調(diào)度,此時(shí)去系統(tǒng)中尋找已經(jīng)就緒的最高優(yōu)先級(jí)的線程進(jìn)行調(diào)度。

這種方式應(yīng)用的場(chǎng)景比較豐富,比如當(dāng)前線程沒(méi)有獲取到資源時(shí),需讓出CPU的使用權(quán),或者事情做完了,主動(dòng)讓出CPU的使用權(quán),這就是系統(tǒng)做調(diào)度的時(shí)機(jī)。

A線程的優(yōu)先級(jí)要高于B線程的優(yōu)先級(jí),所以在A放棄CPU使用權(quán)后,已經(jīng)就緒的最高優(yōu)先級(jí)線程B就開(kāi)始執(zhí)行了。

3.2 被更高優(yōu)先級(jí)的任務(wù)喚醒

這種方式就是當(dāng)比當(dāng)前運(yùn)行線程的優(yōu)先級(jí)高的線程處于就緒態(tài)時(shí),會(huì)調(diào)度到比當(dāng)前線程更高的優(yōu)先級(jí)線程中去。

按照理解A線程是正在運(yùn)行的線程,此時(shí)更高任務(wù)優(yōu)先級(jí)的線程C就緒處于就緒狀態(tài)了,所以系統(tǒng)的tick函數(shù)中判斷已經(jīng)有比線程A更高優(yōu)先級(jí)的線程處于就緒狀態(tài),于是執(zhí)行了rt_schedule()函數(shù)執(zhí)行了系統(tǒng)調(diào)度。當(dāng)前A線程運(yùn)行狀態(tài)壓棧,更高優(yōu)先級(jí)的C線程的狀態(tài)出棧,開(kāi)始運(yùn)行C線程。

3.3 yield放棄cpu使用

首先理解一下什么是yield,解釋成讓出,放棄比較合理。該出讓只針對(duì)于同等優(yōu)先級(jí)的線程。


這種情況只適用于A線程的優(yōu)先級(jí)等于B線程的優(yōu)先級(jí)的情況。因?yàn)镽TT支持同等優(yōu)先級(jí)的方式創(chuàng)建線程,相同的優(yōu)先級(jí)的切換是靠時(shí)間片輪詢來(lái)進(jìn)行的。所以,當(dāng)A線程正常運(yùn)行的時(shí)候,如果執(zhí)行了yield函數(shù),那么只相當(dāng)于將A線程的時(shí)間片消耗完,此時(shí)同等優(yōu)先級(jí)的D線程開(kāi)始運(yùn)行。

由于在RTOS中,需要的是完成任務(wù)的確定性與可靠性,同等優(yōu)先級(jí)的情況比較有限,所以這一塊應(yīng)用的不多。

3.4 中斷中執(zhí)行調(diào)度

以上的三種屬于主動(dòng)進(jìn)行調(diào)度的過(guò)程,其系統(tǒng)的執(zhí)行流程都是可以預(yù)測(cè)的,但是中斷去執(zhí)行調(diào)度卻是比較特殊。是被動(dòng)調(diào)度。

這種方式是在中斷中執(zhí)行調(diào)度的,當(dāng)A線程正常運(yùn)行時(shí),此時(shí)來(lái)了一個(gè)中斷,由于中斷的優(yōu)先級(jí)是高于線程的。所以,中斷處理事情,如果在中斷中執(zhí)行了調(diào)度函數(shù),那么在中斷退出后,將直接切換到當(dāng)前系統(tǒng)中更高優(yōu)先級(jí)的線程去運(yùn)行。如果如果當(dāng)前系統(tǒng)的最高優(yōu)先級(jí)還是A,那么中斷退出后,執(zhí)行的最高優(yōu)先級(jí)線程依然是A。若存在線程E線程優(yōu)先級(jí)高于A并且處于就緒狀態(tài),此時(shí),中斷退出后,切換到E線程去執(zhí)行。

4.調(diào)度做了哪些事情?

系統(tǒng)進(jìn)行調(diào)度的時(shí)候做了哪些事情?

第一步:查找當(dāng)前系統(tǒng)中當(dāng)前以及就緒的最高優(yōu)先級(jí)的線程,若有高于當(dāng)前運(yùn)行系統(tǒng)運(yùn)行的線程棧則執(zhí)行線程切換

第二步:關(guān)閉中斷,將系統(tǒng)當(dāng)前運(yùn)行的寄存器壓入??臻g

第三步:   找到需要運(yùn)行的線程的PC指針,并找到棧起始處彈出棧中的寄存器狀態(tài)

第四部:打開(kāi)中斷,執(zhí)行異常ret,讓系統(tǒng)恢復(fù)執(zhí)行

此時(shí),就切換到已經(jīng)就緒的更高優(yōu)先級(jí)的線程去運(yùn)行了。

5.總結(jié)

rt-thread線程的調(diào)度原理和過(guò)程上述文章已經(jīng)寫(xiě)的比較詳細(xì)了,主要需要注意的是調(diào)度器的原理以及調(diào)度的時(shí)機(jī)的問(wèn)題。往往在利用rt-thread做具體的項(xiàng)目的時(shí)候,需要非常清楚的理解調(diào)度過(guò)程,通過(guò)閱讀代碼,就能預(yù)測(cè)程序下一步的執(zhí)行動(dòng)作。真正的做到手中有糧,心中不慌。


本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
關(guān)閉