線程和優先級
優先級和時間片是線程的兩個重要參數,分別描述線程競爭處理器資源的能力和持有處理器時間長短的能力。
RT-Thread支持256個優先級。數值越小,優先級越高。0為最高優先級,最低優先級預留給空閑線程。用戶可以通過rt_config.h中的RT_THREAD_PRIORITY_MAX宏來修改最大支持的優先級。針對STM32默認設置最大支持32個優先級。
具體應用中,線程總數不受限制,可以創建多個優先級相同的線程。能創建的線程總數只和具體硬件平台的內存有關。
線程時間片
時間片只在相同優先級的就緒態線程中起作用,系統對相同優先級的就緒態線程采用時間片輪轉的調度方式進行調度。時間片起到約束線程單次運行時長的作用,其單位是一個系統節拍(OS Tick)。
假設有2個相同優先級的就緒態線程A和B,A線程的時間片設置為10,B線程的時間片設置為5,那么,當系統中不存在高於A線程優先級的就緒態線程時,系統會在A、B線程間來回切換執行,並且每次對A線程執行10個節拍的時長,對B執行5個節拍的時長。
線程調度規則
優先級搶占調度
操作系統總是讓具有最高優先級的就緒任務有限運行:當有任務的優先級高於當前任務的優先級並且處於就緒態后,就一定會發生系統調度。
通過優先級搶占機制,最大限度地滿足了系統的實時性。
時間片輪詢調度
當操作系統中存在優先級相同的線程時(優先級相同就不會發生搶占),操作系統會按照線程設置的時間片大小輪流調度線程,時間片起到約束線程單次執行時長的作用,其單位是1個系統節拍(OS Tick)。
時間片輪詢調度機制,保證優先級相同的線程輪流占用處理器。
時間片輪詢調度示例
timeslice_sample.c

1 #include <rtthread.h> 2 3 #define THREAD_STACK_SIZE 1024 4 #define THREAD_PRIORITY 20 5 #define THREAD_TIMESLICE 10 6 7 /* 線程入口 */ 8 static void thread_entry(void* parameter) 9 { 10 rt_uint32_t value; 11 rt_uint32_t count = 0; 12 13 value = (rt_uint32_t)parameter; 14 while (1) 15 { 16 if(0 == (count % 5)) 17 { 18 rt_kprintf("thread %d is running ,thread %d count = %d\n", value , value , count); 19 20 if(count > 200) 21 return; 22 } 23 count++; 24 } 25 } 26 27 int timeslice_sample(void) 28 { 29 rt_thread_t tid; 30 /* 創建線程1 */ 31 tid = rt_thread_create("thread1", 32 thread_entry, (void*)1, 33 THREAD_STACK_SIZE, 34 THREAD_PRIORITY, THREAD_TIMESLICE); 35 if (tid != RT_NULL) 36 rt_thread_startup(tid); 37 38 39 /* 創建線程2 */ 40 tid = rt_thread_create("thread2", 41 thread_entry, (void*)2, 42 THREAD_STACK_SIZE, 43 THREAD_PRIORITY, THREAD_TIMESLICE-5); 44 if (tid != RT_NULL) 45 rt_thread_startup(tid); 46 return 0; 47 } 48 49 /* 導出到 msh 命令列表中 */ 50 MSH_CMD_EXPORT(timeslice_sample, timeslice sample);
示例中創建了2個動態線程,在線程創建函數的后兩個參數分別是線程的優先級和時間片。示例中兩個線程的優先級參數是相同的,時間片參數是不同的。
兩個線程使用了同一個入口代碼。
線程代碼中,將線程傳入的參數保存在變量中,並計數。然后打印線程參數和計數值。
代碼是循環執行的形式,但是是順序執行的,因為循環內部有循環跳出。