伦伦影院久久影视,天天操天天干天天射,ririsao久久精品一区 ,一本大道香蕉大久在红桃,999久久久免费精品国产色夜,色悠悠久久综合88,亚洲国产精品久久无套麻豆,亚洲香蕉毛片久久网站,一本一道久久综合狠狠老

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

揭秘!基于RT-Thread探究“優先級反轉”下的任務調度究竟是什么樣的?| 技術集結

RT-Thread官方賬號 ? 2025-08-17 10:07 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

本文將基于RT-Thread,結合 RT-Trace 調試器細化到實際任務調度的粒度,來調試并逐步講解“優先級反轉”的調度和運行邏輯。如果對 RT-Trace 感興趣的可以看這篇文章:

國產嵌入式調試器之光? RT-Trace 初體驗!

廢話不多說,我們直接開始。本文基于 RT-Thread 來編寫測試代碼。在此之前我們先捋一下代碼流程:

優先級反轉問題的本質是高優先級任務因等待低優先級任務釋放資源而被阻塞,同時又有其他中優先級任務搶占了 CPU,使得低優先級任務得不到執行機會,進而導致高優先級任務長時間無法繼續運行。

因此我們需要建立三個不同優先級的任務,然后需要有一個資源鎖來模擬實際場景下對共享資源的獲取與釋放。一般在 RTOS 中我們會使用互斥鎖來對資源進行上鎖,因此絕大多數的 RTOS 已經為互斥鎖這個組件加入了優先級繼承等應對優先級反轉問題的功能,包括 RT-Thread(RTT 的互斥鎖還具備優先級天花板功能),所以如果我們就是想觀察優先級反轉的現象,直接使用互斥鎖是不行的。

幸運的是,在 RT-Thread 中,還有一個線程間同步組件,其是不帶優先級繼承等功能的,并且在我們目前的場景中也可以作為資源鎖來使用,這就是二值信號量。(特別注意,這邊使用二值信號量作為資源鎖只是用于觀察優先級反轉這種異?,F象,并且也正是因為其存在這個問題,實際項目中并不推薦這么使用?。?/strong>

綜上,我們的測試代碼主體就是三個不同優先級的任務,加上一個資源鎖。且我們要測試三種情況,分別是用信號量實現優先級反轉,用互斥鎖實現優先級繼承,在互斥鎖的基礎上通過設置天花板優先級來實現優先級天花板機制,整體測試代碼如下:

#include"rtdef.h"#include"rttypes.h"#include#include#include#include#ifndefRT_USING_NANO#include#endif/* RT_USING_NANO *//* defined the LED0 pin: PB1 */#defineTHREAD_PRIORITY 10#defineUSE_MUTEX 0#defineUSE_PRIORITY_CEILING 0#ifUSE_MUTEXrt_mutex_tmutex;#elsert_sem_tsem;#endifstaticvoidworking(uint32_tnms){ for(volatileuint32_ti =0; i < nms; i++) {? ? ? ? for?(volatileuint32_t?j =?0; j

以上代碼動態創建了三個任務:th、tm和tl,分別對應高優先級(9),中優先級(10)和低優先級(11),在 RT-Thread 中優先級數字越小越高。同時還基于條件編譯定義了一個資源鎖,當USE_MUTEX為0時使用信號量作為鎖,用于制造優先級反轉,為1且USE_PRIORITY_CEILING為0時使用互斥鎖實現優先級繼承,USE_MUTEX以及USE_PRIORITY_CEILING都為1時實現優先級天花板策略。

working 函數本質上是制造一段時間的延遲用于模擬任務的工作流程,此處沒有使用 rt_thread_mdelay 延時的原因是 rt_thread_mdelay 會造成任務本身主動讓出,從而無法實現真實情況下高優先級在低優先級任務運行中的搶占過程。

th 任務首先使用 rt_thread_mdelay 延遲主動讓出使得低優先級任務能夠先運行從而獲取到資源,緊接著嘗試獲取資源,獲取到后使用 working 函數模擬對資源進行的操作,最后釋放資源。

tm 任務首先使用 rt_thread_mdelay 延遲主動讓出使得高優先級任務能夠有時間運行到嘗試獲取資源并阻塞,從而能夠成功制造出中優先級對低優先級任務的搶占。緊接著使用working函數模擬其運行。注意,該任務中沒有任何對資源的操作,也不會獲取與釋放鎖。

tl 任務開始運行后立馬嘗試獲取資源,進而使用working函數模擬對資源進行的操作,接著釋放資源,最后再次使用working函數模擬該任務的其他操作。

在開啟了優先級天花板機制的情況下,互斥鎖創建后會使用 rt_mutex_setprioceiling 為其設置一個天花板優先級,在這里也就是 THREAD_PRIORITY - 2,雖然我們所有任務的最高優先級為 THREAD_PRIORITY - 1,由于 RT-Thread 存在時間片輪轉調度功能,同優先級任務在時間片用完之后也能互相搶占。此處也可以設置一個比較大的時間片來臨時防止搶占,我這里就直接將該優先級設置為更高一級,從根本上避免搶占的發生。

OK,所有功能點都講解完成,接下來我們就借助 RT-Trace 的運行跟蹤功能,進入 CPU 視角,來看看底層的真實運行情況。

首先是使用信號量實現的優先級反轉場景,我們重點關注三個任務之間的運行,屏蔽掉中斷,空閑線程等其他信息:

e70a91ce-7b0e-11f0-9080-92fbcf53809c.png

可以看到 tl 在開始運行了一段時間后 th 發生了搶占并嘗試獲取資源,但由于當前資源被 tl 持有,于是 th 立馬阻塞讓出了 CPU 等待 tl 釋放資源:

e71b7a70-7b0e-11f0-9080-92fbcf53809c.png

然而還沒等 tl 釋放資源,中等優先級的 tm 就搶占了 tl 的運行,此時 th 雖有著最高優先級,但也只能眼睜睜等著 tm 執行完,因為要等 tl 釋放資源它才能運行,但 tl 優先級沒有 tm 高,當前情況下 tm 不運行完, tl 根本不會運行:

e724c404-7b0e-11f0-9080-92fbcf53809c.png

等 tm 終于運行完了,把 CPU 給到 tl,并且 tl 釋放了資源后,本應是最高優先級的 th 才得以運行:

e7330e88-7b0e-11f0-9080-92fbcf53809c.png

由于低優先級任務持有了高優先級任務運行所需的共享資源,從而導致高優先級任務不可避免地進入等待,而當系統比較復雜,任務較多時,低優先級任務又特別容易被其他中優先級任務搶占,最終導致高優先級任務被無限延后,直至所有搶占的任務運行完并且低優先級任務釋放資源才得以運行,而這個過程需要等待多久是未知且不可控的。在很多工業、醫療、軍事領域中,一個任務之所以要定義為高優先級,就是需要其盡快執行,并且運行周期嚴格可控,否則很有可能造成不可挽回的后果,如果這個過程中遇到優先級反轉,那系統異常甚至崩潰幾乎是必然的!

現在我們將 USE_MUTEX 置 1 來使用帶有優先級繼承功能的互斥鎖,此時的任務調度過程如下:

e73ddad4-7b0e-11f0-9080-92fbcf53809c.png

很明顯,此時中優先級任務沒有能搶占低優先級任務在共享資源處理階段的運行,雖然高優先級任務第一次嘗試獲取資源會失敗,但這個過程也臨時抬升了tl的優先級:

e74aeff8-7b0e-11f0-9080-92fbcf53809c.png

而后 tl 得以不被中優先級的 tm 打斷,一路運行到釋放資源,緊接著 th 獲取資源執行,而 tm 自然是等到 th 運行完后才能運行。很明顯,優先級反轉帶來的影響在這種機制下得到大幅緩解,但這里仍然有一個小瑕疵:

e75360c0-7b0e-11f0-9080-92fbcf53809c.png

在 tl 對共享資源進行處理的過程中,仍然發生了一次搶占,這期間還會動態修改任務的優先級,稍許拉長了tl 對資源的處理時間。如果頻繁操作資源,那么這對系統調度來說也是消耗比較大的。如果想要保證高優先級任務能夠盡快執行,那么這一段操作一定是要去除的。如何去除?這就引出了下面這個機制。

我們再將 USE_PRIORITY_CEILING 置 1 打開優先級天花板,注意優先級天花板的值是預設且靜態的,所以我們在使用這個特性的時候需要提前設置好值:

rt_mutex_setprioceiling(mutex, THREAD_PRIORITY -2);

這個值一般會設置成使用資源中所有任務的最高優先級,當然文章開頭也講過由于 RT-Thread 相同優先級可以通過輪轉調度機制相互搶占,我這邊為了避免這種情況,所以設置為最高任務優先級的更高一級。

我們來看下加入了優先級天花板后任務的調度情況:

e75f0e34-7b0e-11f0-9080-92fbcf53809c.png

乍一看好像與優先級繼承的調度情況沒有區別,接下來我將 tl 操作共享資源的時間軸放大:

e7683716-7b0e-11f0-9080-92fbcf53809c.png

對比優先級繼承機制下的這部分:

e7758268-7b0e-11f0-9080-92fbcf53809c.png

可以看到中間 th 對 tl 的搶占過程消失了!

e77eafa0-7b0e-11f0-9080-92fbcf53809c.png

正是由于我們設置了天花板優先級,tl 在獲取資源的那一刻就將其優先級提升到了天花板,因此在這過程中即使是高優先級的 th 也無法對其進行搶占,真正做到了最快的資源處理速度,自然 th 在這種情況下也得到了最快的響應運行速度。

通過上述內容,相信大家已經對優先級反轉,優先級繼承以及優先級天花板有了非常直觀的理解,在實際的項目中也能夠按照實際需求去選擇合適的機制。

最后提一點,以上兩種方式都是緩解優先級反轉帶來的影響,并不能解決,因為低優先級任務獲取到資源后高優先級任務不可避免地要等待,否則就會造成更為致命的數據同步問題,上述解決方案都只是盡可能讓低優先級任務更快速地處理完釋放資源從而讓高優先級任務及時獲取。如果你的系統就不能接受這種情況,那么或許你要從程序設計角度,根本上去避免低優先級任務與高優先級任務共享資源,或是通過精密的設計規避高優先級任務想要獲取資源時低優先級任務正在處理資源的情況。


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 嵌入式
    +關注

    關注

    5208

    文章

    20586

    瀏覽量

    336261
  • 調試器
    +關注

    關注

    1

    文章

    329

    瀏覽量

    25170
  • RT-Thread
    +關注

    關注

    32

    文章

    1632

    瀏覽量

    45115
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    RTOS應用中的優先級反轉問題

    在嵌入式系統中,如果使用基于優先級調度算法的RTOS,系統中可能發生優先級反轉現象。優先級反轉
    發表于 12-14 11:00 ?2065次閱讀

    深度剖析 RT-Thread 線程調度流程

    rt_system_scheduler_start:調度系統第一個線程rt_hw_context_switch_to:初始化上下文切換環境,觸發PendSV異常first_thread
    的頭像 發表于 06-25 18:24 ?1908次閱讀
    深度剖析 <b class='flag-5'>RT-Thread</b> 線程<b class='flag-5'>調度</b>流程

    請問UCOS如果把一個優先級為5的任務刪除后,還能創建另一個優先級為5的任務嗎?

    1,ucos 中不允許有相同優先級任務,如果把一個優先級為5的任務刪除后,我還可以創建另一個優先級為5的
    發表于 05-12 23:05

    干貨 | RTOS應用中的優先級反轉問題

    在嵌入式系統中,如果使用基于優先級調度算法的RTOS,系統中可能發生優先級反轉現象。優先級反轉
    發表于 03-09 15:00

    RT-Thread與UCOS的簡單比較

    一、RT-Thread與UCOS的簡單比較任務或線程調度RT-Thread可選優先級搶占式調度,
    發表于 08-20 06:00

    RT-Thread的內核調度算法實現

    rt-thread調度算法為基于優先級調度和基于時間片輪轉調度共存的策略。rt-thread
    發表于 04-20 11:54

    RT-Thread基于優先級的全搶占式調度算法的實現

    一、原理概述RT-Thread 是一款嵌入式實時操作系統(RTOS),同時也是一款優秀的物聯網操作系統,相對于裸機的輪詢調度算法,它使用的線程(任務調度算法是基于
    發表于 04-20 14:17

    探討一RT-Thread任務調度的啟動順序

    ;amp;(thread->tlist));(f)調用rt_schedule進行調度。首先需要做的就是查找當前最高的優先級RT-Thread
    發表于 05-09 14:13

    rt-thread優先級的線程可以調度執行嗎?

    請教下,在rt-thread中,如果低優先級的線程中用while(1){}直接死循環,是不是高優先級的線程也無法調度執行了?如果高優先級的線
    發表于 05-13 10:51

    RT-Thread線程優先級鏈表與位圖算法的介紹

    1 線程優先級鏈表每個線程控制塊都帶有一個鏈表成員,根據優先級thread->slist插入對相應優先級鏈表中,對于相同優先級采取時間片輪
    發表于 05-13 15:38

    RT-Thread系統線程調度器的設計實現

    。RT-Thread內核中也允許創建相同優先級的線程。相同優先級的線程采用時間片輪轉方式進行調度(也就是通常說的分時調度器),時間片輪轉
    發表于 08-23 15:24

    如何去處理RT-Thread線程優先級的問題呢

    RT-Thread優先級問題,官方文檔互斥量一節,線程2的優先級比線程1高,但在線程2running的時候還是會被線程1搶占,達不到官方文檔的仿真運行結果。下圖是我的仿真運行結果,輸出打印
    發表于 12-05 11:51

    RT-Thread的互斥量優先級問題求解

    優先級最大值25,線程優先級設置為21一25都可恢復正常功能,即高優先級先運行。源代碼如下:/*Copyright (c) 2006-2018, RT-Thread Developme
    發表于 12-09 15:43

    任務優先級分配該遵循什么樣的原則?

    大家好!一直在做基于RT-Thread的多任務程序開發,但是對于多任務優先級該如何分配,并沒有太多的經驗。所以想問一大家,在進行多
    發表于 02-10 14:14

    什么是優先級反轉

    假設現在有三個任務TaskA(優先級高)、TaskB(優先級中)、TaskC(優先級低),一個信號量(Semaphore),此信號量用于任務
    的頭像 發表于 04-24 13:01 ?3542次閱讀
    什么是<b class='flag-5'>優先級</b><b class='flag-5'>反轉</b>