實時操作系統任務調度

最近看了一些實時操作系統的源碼,關於任務調度是實時操作系統的重要組成部分,但是何時發生調度,怎樣才能發生調度卻不是非常的清晰,書中一本而言所說的都是“如果有更高優先級任務就緒,就會發生調度”,這會讓很多的讀者產生很大的歧義:
在當前的任務中,並沒有關於就緒表等全局變量的訪問,當前的任務也有自己的堆棧空間,我並不知道是否有更高優先級的任務就緒,之所以產生這些疑惑是沒有搞清楚什麼時候發生調度,怎麼知道需要調度。當前運行的任務,一般而言就是所謂的最高優先級的任務,在沒有訪問一系列全局變量的過程中,內核又是如何知道存在一個更高優先級的任務被就緒了呢?
 
一般而言,對於搶佔型實時內核,一般在同步、或者通信的過程中會主動的調用調度函數,或者任務的掛起函數中使用調度函數,其他的函數中並沒有發現其他的調度函數,而且這種情況下都是手動的調度任務,那麼在沒有這些函數的情況下,實時操作系統中內核是如何知道需要調度的呢?
 
我仔細查找了一些資料,別人總結了一些操作系統發生調度的原因如下:
  (1)正在執行的進程執行完畢。這時,如果不選擇新的就緒進程執行,將浪費處理機資源。
  (2)執行中進程自己調用阻塞原語將白己阻塞起來進入睡眠等狀態。
  (3)執行中進程調用了P原語操作,從而因資源不足而被阻塞;或調用了v原語操作激活了等待資源的進程隊列。
  (4)執行中進程提出I/O請求後被阻塞。
  (5)在分時系統中時間片已經用完。
  (6)在執行完系統調用等系統程序後返回用戶進程時,這時可看作系統進程執行完畢,從而可調度選擇一新的用戶進程執行。
  以上都是在可剝奪方式下的引起進程調度的原因。在CPU執行方式是可剝奪時.還有
  (7)就緒隊列中的某進程的優先級變得高於當前執行進程的優先級,從而也將引發進程調度。
我對比了在實時操作系統中經常使用的調度方式發現,原因(2)、(3)、(7)是主要的原因,其他的一般在實時操作系統中很難找到。但是這還是不能回答什麼時候發生調度這個問題。
 
我認爲在實時操作系統中發生調度的主要有兩個部分:
(1)自身需要睡眠等待,必須手動的調用調度函數(信息量,或者通信機制)。
(2)發生中斷過,當執行完中斷服務函數以後,需要重新調度。
 
其中原因(2)是我們在分析實時操作系統中實時性能的主要因素,很多人又會有很多的疑問,如果操作系統中很少使用中斷,實質上在實時系統中必須存在的一箇中斷就是時間節拍中斷,這個中斷的存在就能保證實時操作系統的實時型。這個時間節拍選擇也是設計過程中必須注意的。我們可以參看uC/OS-II的時間節拍代碼,其中完成了所有對非任務掛起的任務的就緒操作(時間到期),這時也就知道了那個任務需要我們調度。在其他的中斷服務函數執行完成以後也就需要那個任務需要被執行,進而實現了實時操作。

點擊(此處)摺疊或打開

  1. void OSTimeTick (void)
  2. {
  3. #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
  4.     OS_CPU_SR cpu_sr;
  5. #endif
  6.     OS_TCB *ptcb;

  7.     OSTimeTickHook(); /* Call user definable hook */
  8. #if OS_TIME_GET_SET_EN > 0 
  9.     OS_ENTER_CRITICAL(); /* Update the 32-bit tick counter */
  10.     OSTime++;
  11.     OS_EXIT_CRITICAL();
  12. #endif
  13.     if (OSRunning == TRUE) { 
  14.         ptcb = OSTCBList; /* Point at first TCB in TCB list */
  15.         while (ptcb->OSTCBPrio != OS_IDLE_PRIO) { /* Go through all TCBs in TCB list */
  16.             OS_ENTER_CRITICAL();
  17.             if (ptcb->OSTCBDly != 0) {                     /* Delayed or waiting for event with TO*/
  18.                 if (--ptcb->OSTCBDly == 0) { /* Decrement nbr of ticks to end of delay */
  19.                     if ((ptcb->OSTCBStat & OS_STAT_SUSPEND) == OS_STAT_RDY) { /* Is task suspended? */
  20.                         OSRdyGrp |= ptcb->OSTCBBitY; /* No, Make task R-to-(timed out)*/
  21.                         OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
  22.                     } else {
  23.                             /* Yes, Leave 1 tick to prevent ... */
  24.                         ptcb->OSTCBDly = 1; /* ... loosing the task when the ... */
  25.                     } /* ... suspension is removed. */
  26.                 }
  27.             }
  28.             ptcb = ptcb->OSTCBNext; /* Point at next TCB in TCB list */
  29.             OS_EXIT_CRITICAL();
  30.         }
  31.     }
  32. }
從上面的代碼中我們可以知道每個任務都會被掃描一次,檢測是否能夠就緒,如果能夠就緒就將就緒表中的值設置,這樣也就知道了是否有更高優先級的任務就緒,是否需要調度操作。因爲時間節拍中斷的不斷髮生就能保證最高優先級任務的發生。因此時間節拍中斷函數是在實時操作系統中非常重要的函數之一。當然任務之間切換以及在中斷中切換到新的任務中的切換代碼也是非常重要的,但是這些一般涉及到CPU寄存器的值,需要彙編代碼實現。
因爲中斷完成以後很多的任務可能因爲信號量等信息的釋放已經就緒,這時候必然需要任務的調度操作,這時候也就知道了那個任務是最高優先級的,那個任務應該被執行。這時也就是發生調度的時刻。
 
在UC/OS-II中通常採用關閉中斷的方式進入臨界區,因爲關閉了中斷,所有的中斷服務函數都不會被執行,也就不會發生任務的調度。那麼只有一個情況纔會發生調度,也就是任務自身需要睡眠,手動選擇調度函數,但是在臨界區中不應該發生睡眠等,因此也就不可能手動調度,因此所有發生調度的可能都被清除了,這樣也就保證了臨界區代碼的安全性。

淺談實時操作系統任務調度

 (2011-06-10 18:32:27)
  分類: 作業

一、1、 調度用來確定多任務環境下任務執行的順序在獲得CPU資源能夠執行的時間長度

    2、 操作系統通過一個調度程序來實現調度功能。

   調度程序以函數的形式存在,用來實現操作系統的調度算法。調度程序本身並不是一個任務,是一個函數調用,可在內核的各個部分進行調用。

    3、調用調度程序的具體位置又被稱爲是一個調度點scheduling point),調度點通常處於以下位置中斷服務程序的結束位置;任務因等待資源而處於等待狀態;任務處於就緒狀態時等。

二、調度算法

    從理論上來說,最優調度只有在能夠完全獲知所有任務在處理、同步和通信方面的需求,以及硬件的處理和時間特性的基礎上才能實現。實際的應用很難實現,特別是需要獲知的信息處於動態變化的情況下。即使在這些需要的信息都是可以預見的情況下,常用的調度問題仍然是一個NP難題。調度的複雜性將隨調度需要考的任務和約束特性的數量呈現出指數增長。調度算法不能很好地適應系統負載和硬件資源不斷增長的系統。當然,這並不意味着調度算法不能解決只有少量、定義好的任務的應用的需求。

   嵌入式實時操作系統兼有嵌入式和實時性的特點。作爲一種嵌入式操作系統,它具有嵌入式軟件共有的可裁剪、低資源、低功耗等特點;作爲實時操作系統除了要滿足應用的功能需求以外,更重要的是還要滿足應用提出的實時性要求。實時操作系統所遵循的最重要的# #設計原則是:採用各種算法和策略始終保證系統行爲的可預測性。實時操作系統的首要任務是調動一切可利用的資源完成實時控制任務。如何使任務集內各任務滿足各自的時限,使系統得以正常、高效率工作的任務調度算法一直是實時系統領域內研究的焦點。根據其應用領域及追求精簡、高設角度的不同,任務調度算法從簡單的合理安排任務循環,發展到基於優先級的速率單調調(RMs)、最早時限優先(EDF)等算法。任務調度算法的好壞以及執行效率直接關係到嵌入式內核的應用範圍及實時性程度。

1、各種實時操作系統的實時調度算法可以分爲如下三種類別

基於優先級的調度算法(Priority-driven scheduling-PD)、基於CPU使用比例的共享式的調度算法(Share-drivescheduling-SD)、以及基於時間的進程調度算法(Time—driven schedulinq-TD),下面對第一種調度算法進行重點介紹。

   基於優先級的調度算法給每個進程分配一個優先級,在每次進程調度時,調度器總是調度那個具有最高優先級的任務來執行。根據不同的優先級分配方法,基於優先級的調度算
法可以分爲如下兩種類型

1.1 靜態調度
    靜態調度是在系統開始運行前進行調度的,嚴格的靜態調度在系統運行時無法對任務進行重新調度。靜態調度的目標是把任務分配到各個處理機,並對每一處理機給出所要運行任務的靜態運行順序。靜態調度算法實現簡單,調度的額外開銷小,在系統超載時可預測性好。但也具有很大的侷限性,例如資源利用率低、受系統支持的優先級個數限制以及靈活性和自適應性差等。

1.2 動態調度
    在嵌入式實時系統中,動態調度依賴於任務的優先級。優先級可以靜態分配或者依據不同的特徵參數,如截止時問、空閒時間或關鍵性(即任務的重要程度)等進行動態分配。動態
調度可以是搶佔式的或非搶佔式的。當檢查到一事件時,動態搶佔式算法立即決定是運行與此事件相關的任務,或繼續執行當前的任務;對於動態非搶佔式算法,它僅僅知道有另一
個任務可以運行,在當前任務結束後,它纔在就緒的任務中選擇一個來運行。

三、調度算法的選擇 嵌入式實時系統中資源是非常有限的,所以開銷要儘可能小。開銷主要包括運行開銷和調度開銷。運行開銷與隊列分析和從調度隊列中增加、刪除任務相關。每個任務在一個調度週期內至少被阻塞和喚醒一次,所以任務調度器在一個週期內不得不對一個任務進行兩次選擇。靜態算法根據任務的執行頻率設置優先級,有較小的運行開銷,但執行頻率最高的任務不一定是最重要的。EDF算法中則是對整個任務列表的調度開銷進行全面比較,選擇最高優先級任務進行調度,有較小的調度開銷,但對多個任務具有同一優先級的情況考慮不足。基於優先級的調度算法在實時進程調度中使用很廣泛,靜態優先級調度算法根據應用的屬性來分配優先級,其可控性較強,而動態優先級調度算法在資源分配和調度時具有更大的靈活性。如果結合這兩種算法的優點,揚長避短,就能夠對實時任務進行更合理、更高效的任務調度。利用最著名的動態優先級調度算法一EDF算法的高CPU利用率、可調度較大的任務集的特點,結合靜態優先級調度算法的可控性就形成了一種新的調度算法-NEDF、調度算法(New Earliest Dead—line First)。

 NEDF算法概述
NEDF算法以任務的截止期限作爲任務調度的首要指標,但不是唯一的指標。當兩任務的截止期限在一定的IM值範圍內時,根據任務的優先級來決定要運行的任務,這時以任務的靜態優先級來選擇任務,一定程度上增強了算法的可控性。確定任務的靜態優先級,主要依據有以下幾個。
(1)執行時間
以執行時間爲依據,執行時間越短,靜態優先級越高。
(2)任務週期
以任務週期爲依據,任務週期越短,靜態優先級越高。
(3)任務的CPU利用率
任務的CPU利用率爲任務執行時間與任務週期的比值(生)。仟各的CPU利基於Linux的實時操作系統研究用率越高,靜態優先級越高。(4)任務緊急程度根據任務的緊急程度,人爲安排任務的優先級。任務越緊急,靜態優先級越高。
 算法說明
先假定任務的優先級均不相同,則在某個調度時刻t,NEDF算法先查找距截止期限最近的任務。這時,可能有多個任務的截止期限相等或較爲接近。如果截止期限相等,則選擇
高優先級的任務運行。如果截止期限均不相等,且最小截止期限比次小截止期限小許多,則選擇最小截止期限的任務運行。若最小截止期限與次小截止期限的差值在一定的IM值範圍
內,則選擇高優先級的任務運行。截止期限IM 值的設定應保證最高優先級任務能夠如期完成,一般可取最小相對截止期限的值,以確保在最小相對截止期限的週期範圍內,最高優先
級任務能夠優先運行。


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