主要產品系列 |
任務調度(schedulers)是內核的主要職責,實際上它就是一個法官,決定當前由哪個任務占用CPU,多數實時內核都是基于優先級調度算法的,每個任務根據其重要程度的不同被賦予一定的優先級。基于此算法,CPU總是讓處于就緒而且優先級最高的任務優先運行,然而何時高優先級任務能夠得到CPU使用權,由內核的類型而定。基于優先級的內核有兩種:
不可搶占型和搶占型。
1) 不可搶占型內核:
不可搶占型內核要求每個任務主動放棄CPU的使用權,其間不能被高優先級任務搶占。它的特點是:
但它的最大缺點是:響應時間不確定,當有更高優先級任務就緒后,不知道什么時候才能得到執行,這在實時系統中是致命的缺陷。所以不可搶占型內核主要用于前后臺系統中。
2) 搶占型內核:
在嵌入式系統中,進程(任務)都是搶占型的,通過給每個進程(任務)設置一個優先級,當系統中有優先級比當前運行的進程(任務)的優先級更高的進程(任務)時,當前的進程(任務)執行被中斷,并調用調度程序選擇優先級高的進程(任務)運行。利用搶占式內核,可以保證高優先級的進程(任務)被優先執行,從而保證系統的實時響應。
在多任務系統中,都會提供一個系統函數來進行進程(任務)間切換,綜合來說,他們有兩種進程(任務)切換方式:
1) 由進程(任務)本身直接調用任務切換函數進行進程(任務)切換:
在當前進程(任務)因為不能獲得必須的資源而立即被堵塞時,就由進程(任務)本身直接調用進程(任務)切換函數進行進程(任務)間調度。 在Linux中可以直接調用schedule()函數來實現。 在UCos中,通過調用OSSched()來完成。
2) 延遲調用任務切換函數進行進程(任務)切換:
此方式是把當前進程(任務)設置一調度標志而以延遲方式調用任務切換函數進行進程(任務)切換。 在Linux系統中,總是在恢復用戶態進程執行之前,檢查這一調度標志,在這里標志是:TIF_NEED_RESCHED,如果有這一標志,就調用調度函數進行進程切換。此種情況主要包括以下幾種:
在這些情況中,主要由于系統調用或中斷而進入內核態,或者當前進程本來在內核態時,返回用戶態時發生的。 在UCOS中,所有的任務有不同的優先級,不會出現同一優先級上有多個任務的情況,而且也沒有系統調用的概念,所以任務調度的延遲調用只能出現在中斷處理完成返回時,在OSIntExt()函數中,檢查是否有高優先級的任務就緒,如果有高優先級的任務就緒,進行任務切換。
在Linux系統中,選用了比較復雜的調度算法,按照調度類型可以分為以下幾種:
SCHED_FIFO:此算法主要應用于實時進程,當調度程序把CPU分配給當前進程后,如果沒有更高優先級的進程可以運行時,此進程會一直占用CPU直到此進程退出或者自愿放棄CPU,即使此時有其他相同優先級的進程存在。
SCHED_RR:時間片輪詢的實時進程,對于不同優先級的進程會調度優先級高的進程運行,對具有相同優先級的進程,會根據時間片來調度,當當前進程的時間片用完后,會調度相同優先級的其他進程運行,從而保證相同優先級進程的CPU調度公平性。
SCHED_NORMAL:此算法主要用于普通進程,利用分時進行調度。
在UCOS系統中,所有的任務都是實時任務,所以沒有普通任務調度機制,而且為了簡化調度算法,不同的任務有不同的優先級,不可能出現同一優先級有多個任務的情況,實際上它的調度算法就只有Linux中SCHED_FIFO這一種,即優先級高的任務搶占優先級低任務。
上下文切換是多任務調度的核心內容,也是我們感覺在一個CPU上并行運行多個程序的基礎。
任務上下文(Task Context): 任務上下文是指任務運行的環境。例如,針對x86的CPU,任務上下文可包括程序計數器、堆棧指針、通用寄存器的內容。 上下文切換(Context Switching):在多任務系統中,上下文切換是指CPU的控制權由運行任務轉移到另外一個就緒任務時所發生的事件,當前運行任務轉為就緒(或者掛起、刪除)狀態,另一個被選定的就緒任務成為當前任務。上下文切換包括保存當前任務的運行環境,恢復將要運行任務的運行環境。上下文的內容依賴于具體的CPU。
對于不同的硬件體系結構,上下文切換的內容不一樣,本質上有下面兩步:
在搶占式內核中,利用中斷來實現上下文切換是一個非常理想的機制。中斷發生時,中斷會強制CPU把控制權交給操作系統,也就相當于一次上下文切換。這樣不僅可以減少程序出錯的后果,而且提高切換的效率。UCOS就是利用中斷機制進行上下文切換的典型例子。 在UCOS中,如果調度程序決定任務需要切換,就會調用上下文切換OS_TASK_SW()進行實際的上下文切換。OS_TASK_SW()是宏調用,含有微處理器的軟中斷指令,利用此中斷來實現任務之間的上下文切換。所以OS_TASK_SW()是一個體系結構相關的宏,對于不同的硬件體系機構,有不同的實現方式,這也是UCOS在不同硬件體系結構中移植的一個要點。
由于UCOS不支持虛擬內存,所以不需要進行頁目錄切換,其他許多實時多任務嵌入式系統的一個特征,也是區別Linux系統的一個重要方面。
在2.6 Linux kernel中,引入了一個全新的調度機制O(1)調度器,它能在固定的時間內完成進程切換。如果調度程序決定任務需要切換,就會調用上下文切換函數context_switch()函數進行上下文切換,此函數會調用switch_mm()切換頁全局目錄以安裝一個新的地址空間,然后調用switch_to()切換具體硬件上下文。
這里主要介紹了多任務系統中的任務調度及其算法,比較了Linux系統和UCOS系統中的上下文切換,具體實現可以參考Linux內核源代碼和UCOS源代碼。
相關閱讀:uc/os操作系統簡介
聲明:本站部分內容根據互聯網資料整理而成,若侵犯您的權益,請聯系我們,我們會盡快處理。