今天就跟大家聊聊有關(guān)如何進(jìn)行rt-thread的線程調(diào)度與管理,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結(jié)了以下內(nèi)容,希望大家根據(jù)這篇文章可以有所收獲。
十余年的延吉網(wǎng)站建設(shè)經(jīng)驗(yàn),針對設(shè)計(jì)、前端、開發(fā)、售后、文案、推廣等六對一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。全網(wǎng)整合營銷推廣的優(yōu)勢是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整延吉建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)公司從事“延吉網(wǎng)站設(shè)計(jì)”,“延吉網(wǎng)站推廣”以來,每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。
調(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)先級,然后去執(zhí)行當(dāng)前最高優(yōu)先級的就緒的線程。
調(diào)度又可以細(xì)分為兩種??纱驍嗾{(diào)度:關(guān)鍵防止優(yōu)先級倒置 ;不可打斷調(diào)度:先來先服務(wù),不可中斷。
在創(chuàng)建任務(wù)的時(shí)候,指定了任務(wù)的優(yōu)先級,一般來說,每個(gè)任務(wù)都有自己特定的優(yōu)先級。所以內(nèi)核線程對象中有不同的優(yōu)先級的任務(wù)列表。
如果最大指定為32個(gè)優(yōu)先級,那么可以用u32,每一個(gè)bit表示一個(gè)優(yōu)先級就緒的狀態(tài)。使用位圖的優(yōu)點(diǎn)就是速度快,而且內(nèi)存占用小。
一般來說,調(diào)度去找到最高優(yōu)先級的任務(wù)時(shí),就需要去做判斷。如何去找到最高優(yōu)先級的任務(wù)。一般來說,有兩種辦法:
這兩種的差別僅僅在于計(jì)算效率的問題,本質(zhì)目的并無差別。
而尋找最高優(yōu)先級的事情也是有兩種實(shí)現(xiàn)的策略:
1.遍歷就緒的隊(duì)列,找到最小的就緒的隊(duì)列,尋找的時(shí)間不確定,時(shí)間復(fù)雜度O(n)。
2.采用空間換時(shí)間的辦法,事先做好一個(gè)bitmap
例如系統(tǒng)中最大有8個(gè)優(yōu)先級,那么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)先級是5+1=6。所以可以得出系統(tǒng)的優(yōu)先級,此時(shí)計(jì)算的復(fù)雜度為O(1)。
雖然rtt是支持同等優(yōu)先級的,但是在具體的業(yè)務(wù)邏輯的設(shè)計(jì)中,在使用RTOS常用的設(shè)計(jì)方法中,一般都是要求程序的運(yùn)行邏輯是可預(yù)測的,就是在程序執(zhí)行的過程中,可以預(yù)測到程序下一步的動(dòng)作。所以rtos中同等優(yōu)先級,按照時(shí)間片輪訓(xùn)的這種方式設(shè)計(jì)業(yè)務(wù)邏輯的情況并不多。使用相同優(yōu)先級會(huì)增加系統(tǒng)的業(yè)務(wù)邏輯的復(fù)雜性。
RTT是搶占式的系統(tǒng)調(diào)用,所以系統(tǒng)什么時(shí)候去做的調(diào)度非常的關(guān)鍵。系統(tǒng)調(diào)度分為主動(dòng)調(diào)度和被動(dòng)兩種。
當(dāng)A線程在正常運(yùn)行時(shí),主動(dòng)放棄CPU的使用權(quán),比如去執(zhí)行rt_thread_delay或者去等待一個(gè)IPC的事件到來時(shí),都會(huì)釋放CPU進(jìn)行調(diào)度,此時(shí)去系統(tǒng)中尋找已經(jīng)就緒的最高優(yōu)先級的線程進(jìn)行調(diào)度。
這種方式應(yīng)用的場景比較豐富,比如當(dāng)前線程沒有獲取到資源時(shí),需讓出CPU的使用權(quán),或者事情做完了,主動(dòng)讓出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í)行了。
這種方式就是當(dāng)比當(dāng)前運(yùn)行線程的優(yōu)先級高的線程處于就緒態(tài)時(shí),會(huì)調(diào)度到比當(dāng)前線程更高的優(yōu)先級線程中去。
按照理解A線程是正在運(yùn)行的線程,此時(shí)更高任務(wù)優(yōu)先級的線程C就緒處于就緒狀態(tài)了,所以系統(tǒng)的tick函數(shù)中判斷已經(jīng)有比線程A更高優(yōu)先級的線程處于就緒狀態(tài),于是執(zhí)行了rt_schedule()函數(shù)執(zhí)行了系統(tǒng)調(diào)度。當(dāng)前A線程運(yùn)行狀態(tài)壓棧,更高優(yōu)先級的C線程的狀態(tài)出棧,開始運(yùn)行C線程。
首先理解一下什么是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)用的不多。
以上的三種屬于主動(dòng)進(jìn)行調(diào)度的過程,其系統(tǒng)的執(zhí)行流程都是可以預(yù)測的,但是中斷去執(zhí)行調(diào)度卻是比較特殊。是被動(dòng)調(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í)行。
系統(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)行的寄存器壓入??臻g
第三步: 找到需要運(yùn)行的線程的PC指針,并找到棧起始處彈出棧中的寄存器狀態(tài)
第四部:打開中斷,執(zhí)行異常ret,讓系統(tǒng)恢復(fù)執(zhí)行
此時(shí),就切換到已經(jīng)就緒的更高優(yōu)先級的線程去運(yùn)行了。
看完上述內(nèi)容,你們對如何進(jìn)行rt-thread的線程調(diào)度與管理有進(jìn)一步的了解嗎?如果還想了解更多知識或者相關(guān)內(nèi)容,請關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝大家的支持。
當(dāng)前題目:如何進(jìn)行rt-thread的線程調(diào)度與管理
網(wǎng)站路徑:http://www.rwnh.cn/article22/gpoicc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供Google、外貿(mào)網(wǎng)站建設(shè)、用戶體驗(yàn)、網(wǎng)站排名、微信小程序、云服務(wù)器
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)