線程與線程就緒列表:編程
在RTT系統中,鏈表是一個至關重要的數據結構,RTT經過鏈表,來管理一些事物,例如說線程。數組
在線程控制塊中,有一個線程鏈表節點:數據結構
rt_list_t tlist; /**< the thread list */
這個節點能夠將線程控制塊掛載到一些鏈表中。在線程建立以後,線程首先被添加到就緒列表中,就緒列表也被叫作線程優先級表。ui
就緒列表其實是一個 rt_list_t 的數組。rt_list_t 是一個RTT定義的雙向鏈表類型,也就是說,這個數組的每一個元素都是一個雙向鏈表。spa
/*就緒列表數組定義,在scheduler.c中*/ rt_list_t rt_thread_priority_table[RT_THREAD_PRIORITY_MAX]; /*RT_THREAD_PRIORITY_MAX定義,在rtconfig.h中*/ /*這裏定義爲32,決定了線程的優先級有多少個,這是RTT的優勢之一*/ #define RT_THREAD_PRIORITY_MAX 32
這裏咱們得知,數組的下標對應了線程的優先級,在RTT系統中,優先級數字越小,邏輯優先級越高。線程
在實際運行流程中,RTT經過rt_thread_startup來將線程插入到就緒列表/線程優先級表中。code
線程調度:blog
如今,咱們擁有了線程優先級表,接下來要實現的就是線程調度。it
線程調度經過調度器來完成,調度器是RTOS系統的核心。io
在調度器以前,先來看下RTT系統爲了調度所設立的一個數——線程優先級組。
#if RT_THREAD_PRIORITY_MAX > 32 /* Maximum priority level, 256 */ rt_uint32_t rt_thread_ready_priority_group; rt_uint8_t rt_thread_ready_table[32]; #else /* Maximum priority level, 32 */ rt_uint32_t rt_thread_ready_priority_group; #endif
在這裏,咱們使用的MAX數小於等於32,因此使用的是else以後的定義。
線程優先級組是來作什麼的?這裏舉一個荔枝:線程3準備好了,這時,優先級組的第3位就會置1,而後線程會被插入優先級表組(就緒列表)的第3個鏈表中。
而後在下一個系統週期中,調度器會從優先級組中發現優先級最高且置1的位,而且根據這個位從相應的優先級表中讀取線程控制塊,並跳轉到這個線程上。具體識別位置並進行跳轉的機制是經過一個已經定義的數組實現,在kservice.c中定義,這裏不詳細討論。
線程的狀態與須要編程事項:
RTT系統中的每一個線程都有多種運行的狀態:
初始態:剛建立時的線程狀態
就緒態:線程在就緒列表中/優先級表中,等待調度運行
運行態:顧名思義,正在運行的線程
掛起態:正在運行的線程被掛起,被阻塞延時,等待信號時的狀態,此時線程不在就緒列表中
關閉態:線程結束
需注意什麼?
首先,在線程中,是不容許出現不讓出CPU的死循環的,線程必須在非活躍狀態下進入掛起或者阻塞,即便是優先級很是高的線程,也必須讓出必定時間,或者在一段時間後結束,不然RTOS系統就失去了意義。
其次,不管是哪一種方式編程,中斷都應該儘可能要短,通常只是進行標記,太長的中斷有時對系統會產生巨大的不利影響。
最後,既然RTOS,就要考慮其實時性,這裏的實時是一個相對的指標,各個線程的實時響應時間都應符合具體的要求(例如響應時間小於5ms)。
(我的水平有限,文中可能有偏頗的地方,望理解=)