VxWorks中的任務及排程(五):VxWorks任務排程機制
第四節: VxWorks任務排程機制
在作業系統中,任務排程存在兩種方式:基於優先順序排程和基於時間片排程。嵌入式系統中任務排程一般都是基於優先順序的排程方式,VxWorks也就是傳說中的搶佔式排程。有沒有方法可以關閉這種搶佔式排程呢?VxWorks作業系統定義了一個全域性變數roundRobinOn用於表示時間片輪轉使能,系統預設該值為FALSE,即VxWorks預設是基於優先順序的任務排程,也就是說當高優先順序任務ready時CPU將交給高優先順序任務。(見原始碼kernelLib.c, kernelInit())當低優先順序任務被高優先順序任務搶佔後,會發生什麼呢?當系統中存在多個優先順序相同的任務
有一種說法是:作業系統可以選擇在相同優先順序的任務間採用時間片輪轉的方式,即如果任務A、任務B、任務C優先順序都為80,那麼A執行時間t後由任務B執行,再過時間t後任務C執行。雖然這是一種明確的排程演算法,但是閱讀程式碼和觀察系統執行未發現此種方式的有效支撐,至少在FH的系統中並沒有使用這種方式。眾所周知,只有為ready狀態的任務才可能獲取cpu進入執行狀態,儘管認為處於pend狀態的最高優先順序任務獲取所需資源後直接進入running狀態,但個人認為到不如理解為處於pend狀態的任務獲取資源進入ready狀態,因為優先順序最高再進入running狀態。
VxWorks系統內部維護一個
有什麼方法可以阻止CPU被高優先順序任務搶佔麼?taskLock()可以暫時關閉VxWorks5.x的優先順序搶佔排程機制。但taskLock()只能關閉排程任務,不能關閉中斷。
未發生優先順序搶佔時任務何時會放棄CPU的使用權呢?資源!系統資源!正在執行的任務一旦缺乏某種系統資源時,便會切換出執行狀態!如果缺乏CPU,會進入ready狀態,缺乏其他資源時,便會進入
這裡有一個問題:如果有兩個任務:任務A優先順序為10,任務B優先順序為80,任務A阻塞於訊息佇列gMsg1(msgQReceive(gMsg1)),gMsg1在任務B中發生(msgQSend(gMsg1)), 如果CPU被位於中間優先順序的任務搶佔,Task B始終不能得到CPU控制權,那麼Task A是否將永久阻塞呢?
為避免這種情況,VxWorks 引進優先順序繼承機制。 為使用優先順序繼承機制,當使用互斥訊號量時,VxWorks 提供了一個附加的選項 SEM_INVERSION_SAFE,它允許使用優先順序繼承演算法,該演算法保證佔有一個資源的任務,在其執行時,其優先順序等於阻塞在該資源上的所有任務的優先順序的最高值。當執行完成,這個任務釋放資源,返回正常的優先順序。因此,這個繼承了最高優先順序的任務, 將不會被優先順序比它的正常優先順序高但又比繼承的優先順序低的任務搶佔。
在本例中,當Task A阻塞於gMsg1時,Task B則繼承Task A的優先順序為10直到Task B 執行完msgQSend.