內核調度
- Zephyr 內核的調度器是基于什么原則選擇當前執行線程的?
總是選擇優先級最高的就緒線程作為當前線程。
當多個線程優先級相同時,調度器會如何選擇?
- 線程的 “就緒狀態” 和 “非就緒狀態” 分別指什么?哪些情況會導致線程進入非就緒狀態?
有無阻塞執行的因子來區分就緒和非就緒態。
未啟動、等待內核對象、等待超時服務、被掛起、已結束或終止
- 協作式線程和搶占式線程在優先級范圍、執行特性上有何本質區別?如何通過動態調整優先級實現兩者的轉換?
協作:優先級為負數,一旦成為當前線程則一直執行直到主動釋放cpu
搶占:優先級非負,運行時可以被任何更高優先級的線程或者協作式的線程搶占。
初始值優先級可以在線程啟動后動態增加或減少,通過改變線程優先級可以改變線程的調度方式
- 協作式線程如果需要執行長時間計算,可能會帶來什么問題?可以通過哪些方法解決?
會導致優先級高于或者等于該線程的其他所有線程的調度被延遲到一個不可接受的時間之后
解決:協作式線程可以自身間或性的放棄cpu,讓其他線程得以執行,具體來說,可以 1. 調用 k_yield
,把線程放到調度器維護的優先級排列的就緒線程鏈表中,然后調用調度器 2. k_sleep()
使該線程在一段指定時間內變為非就緒態的線程。
- 搶占式時間片的作用是什么?其時間片大小是否可配置?當時間片結束時,調度器會對當前搶占式線程執行什么操作?
將同優先級的線程得到調度,可以配置,可以運行期間修改
時間片結束時,會檢查當前線程是否可以搶占,如果可以,則對該線程隱式調用 k_yield()
,讓其他同優先級的就緒線程在該線程再次被調度前得到運行。
- 調度器鎖(k_sched_lock()和k_sched_unlock())的功能是什么?如果持有調度器鎖的線程進入非就緒狀態,再次恢復執行時鎖的狀態會如何變化?
搶占式線程希望在執行某個特殊的操作時不被搶占,可以使用k_sched_lock()
。臨時變成協作式線程。
會把這個鎖定的線程切換出去
- 線程睡眠(k_sleep())和忙等待(k_busy_wait())的核心區別是什么?分別適用于什么場景?
延遲一段時間后再執行,到達執行時間后,線程變為就緒態,然后才能再次被調度
忙等待不會交出cpu給其他線程
- 若要讓某個搶占式線程在執行特定操作時不被搶占,應如何實現?操作完成后又該如何處理?
調用調度器鎖
配置選項CONFIG_NUM_COOP_PRIORITIES和CONFIG_NUM_PREEMPT_PRIORITIES分別影響什么?舉例說明它們如何定義線程的優先級范圍。
當 ISR(中斷服務程序)觸發時,對當前正在執行的線程(包括協作式和搶占式)會產生什么影響?