rtthread使用總結

RT-Thread 中,實際上線程並不存在運行狀態,就緒狀態和運行狀態是等同的。

 

若某線程運行完畢,系統將自動刪除線程:自動執行 rt_thread_exit() 函數,先將該線程從系統就緒隊列中刪除,再將該線程的狀態更改爲關閉狀態,不再參與系統調度,然後掛入 rt_thread_defunct 殭屍隊列(資源未回收、處於關閉狀態的線程隊列)中,最後空閒線程會回收被刪除線程的資源。

 

動態的是create/delete 靜態的是init/detach

 

需要注意的是,用戶提供的棧首地址需做系統對齊(例如 ARM 上需要做 4 字節對齊)。線程初始化接口 rt_thread_init() 的參數和返回值見下表:

 

使線程讓出處理器資源

當前線程的時間片用完或者該線程主動要求讓出處理器資源時,它將不再佔有處理器,調度器會選擇相同優先級的下一個線程執行。線程調用這個接口後,這個線程仍然在就緒隊列中。線程讓出處理器使用下面的函數接口:

rt_err_t rt_thread_yield(void);

通常不應該使用這個函數來掛起線程本身,如果確實需要採用 rt_thread_suspend() 函數掛起當前任務,需要在調用 rt_thread_suspend() 函數後立刻調用 rt_schedule() 函數進行手動的線程上下文切換。用戶只需要瞭解該接口的作用,不推薦使用該接口。

 

空閒線程是一個線程狀態永遠爲就緒態的線程,因此設置的鉤子函數必須保證空閒線程在任何時刻都不會處於掛起狀態,例如 rt_thread_delay(),rt_sem_take() 等可能會導致線程掛起的函數都不能使用。

 

關於刪除線程:大多數線程是循環執行的,無需刪除;而能運行完畢的線程,RT-Thread 在線程運行完畢後,自動刪除線程,在 rt_thread_exit() 裏完成刪除動作。用戶只需要瞭解該接口的作用,不推薦使用該接口(可以由其他線程調用此接口或在定時器超時函數中調用此接口刪除一個線程,但是這種使用非常少)。

 

RT-Thread 定時器默認的方式是 HARD_TIMER 模式,即定時器超時後,超時函數是在系統時鐘中斷的上下文環境中運行的。

 

線程的同步方式有很多種,其核心思想都是:在訪問臨界區的時候只允許一個 (或一類) 線程運行。進入 / 退出臨界區的方式有很多種:

1)調用 rt_hw_interrupt_disable() 進入臨界區,調用 rt_hw_interrupt_enable() 退出臨界區;詳見《中斷管理》的全局中斷開關內容。

2)調用 rt_enter_critical() 進入臨界區,調用 rt_exit_critical() 退出臨界區。

 

信號量可以實現線程間同步,也可以實現互斥的作用,不過會引起優先級反轉,建議使用互斥鎖來實現,不會引起優先級反轉。

 

信號量的使用場合

信號量是一種非常靈活的同步方式,可以運用在多種場合中。形成鎖、同步、資源計數等關係,也能方便的用於線程與線程、中斷與線程間的同步中。

中斷與線程間的互斥不能採用信號量(鎖)的方式,而應採用開關中斷的方式。

 

在 RT-Thread 操作系統中,互斥量可以解決優先級翻轉問題,實現的是優先級繼承算法。優先級繼承是通過在線程 A 嘗試獲取共享資源而被掛起的期間內,將線程 C 的優先級提升到線程 A 的優先級別,從而解決優先級翻轉引起的問題。

 

事件集主要用於線程間的同步,與信號量不同,它的特點是可以實現一對多,多對多的同步。

 

事件集的使用場合

事件集可使用於多種場合,它能夠在一定程度上替代信號量,用於線程間同步。一個線程或中斷服務例程發送一個事件給事件集對象,而後等待的線程被喚醒並對相應的事件進行處理。但是它與信號量不同的是,事件的發送操作在事件未清除前,是不可累計的,而信號量的釋放動作是累計的。事件的另一個特性是,接收線程可等待多種事件,即多個事件對應一個線程或多個線程。同時按照線程等待的參數,可選擇是 “邏輯或” 觸發還是 “邏輯與” 觸發。這個特性也是信號量等所不具備的,信號量只能識別單一的釋放動作,而不能同時等待多種類型的釋放。

郵箱 4*size ,每次只能傳輸4字節數據

消息隊列 n*size 每次傳輸n字節數據。

郵箱是一種簡單的線程間消息傳遞方式,特點是開銷比較低,效率較高。在 RT-Thread 操作系統的實現中能夠一次傳遞一個 4 字節大小的郵件,並且郵箱具備一定的存儲功能,能夠緩存一定數量的郵件數 (郵件數由創建、初始化郵箱時指定的容量決定)。郵箱中一封郵件的最大長度是 4 字節,所以郵箱能夠用於不超過 4 字節的消息傳遞。由於在 32 系統上 4 字節的內容恰好可以放置一個指針,因此當需要在線程間傳遞比較大的消息時,可以把指向一個緩衝區的指針作爲郵件發送到郵箱中,即郵箱也可以傳遞指針

 

消息隊列的使用場合

消息隊列可以應用於發送不定長消息的場合,包括線程與線程間的消息交換,以及中斷服務例程中給線程發送消息(中斷服務例程不能接收消息)。下面分發送消息和同步消息兩部分來介紹消息隊列的使用。

信號的工作機制

信號在 RT-Thread 中用作異步通信,POSIX 標準定義了 sigset_t 類型來定義一個信號集,然而 sigset_t 類型在不同的系統可能有不同的定義方式,在 RT-Thread 中,將 sigset_t 定義成了 unsigned long 型,並命名爲 rt_sigset_t,應用程序能夠使用的信號爲 SIGUSR1(10)和 SIGUSR2(12)。

信號本質是軟中斷,用來通知線程發生了異步事件,用做線程之間的異常通知、應急處理。一個線程不必通過任何操作來等待信號的到達,事實上,線程也不知道信號到底什麼時候到達,線程之間可以互相通過調用 rt_thread_kill() 發送軟中斷信號。

通過上述的計算過程,我們可以看出其中的一些關鍵因素:發送數據量越小,發送速度越快,對於數據吞吐量的影響也將越大。歸根結底,取決於系統中產生中斷的頻度如何。當一個實時系統想要提升數據吞吐量時,可以考慮的幾種方式:

1)增加每次數據量發送的長度,每次儘量讓外設儘量多地發送數據;

2)必要情況下更改中斷模式爲輪詢模式。同時爲了解決輪詢方式一直搶佔處理機,其他低優先級線程得不到運行的情況,可以把輪詢線程的優先級適當降低。

由於關閉全局中斷會導致整個系統不能響應中斷,所以在使用關閉全局中斷做爲互斥訪問臨界區的手段時,必須需要保證關閉全局中斷的時間非常短,例如運行數條機器指令的時間。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章