任務排程與上下文切換

2021-09-24 13:04:02 字數 2625 閱讀 5649

2019獨角獸企業重金招聘python工程師標準》

任務排程(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源**。

任務排程與上下文切換時間測試

建立兩個程序 實時程序 並在它們之間傳送乙個令牌,如此往返傳送一定的次數。其中乙個程序在讀取令牌時就會引起阻塞。另乙個程序傳送令牌後等待其返回時也處於阻塞狀態。傳送令牌帶來的開銷與上下文切換帶來的開銷相比,可以忽略不計 經測試,一次管道傳遞約用時3ns左右 利用管道傳遞令牌 方法一 使用gettim...

上下文切換

1 系統呼叫 一次系統呼叫其實是發生了兩次cpu上下文的切換 首先將使用者態的cpu暫存器中的指令儲存在系統核心中。為了執行核心態 需要將暫存器更新為核心態指令的位置,然後跳轉到核心空間去執行任務。當核心態的指令執行完成的時候,cpu暫存器將恢復儲存在系統核心中的上一次執行的使用者態,然後切換到使用...

上下文切換

上下文切換 有時也稱做程序切換或任務切換 是指 cpu 從乙個程序或執行緒切換到另乙個程序或執行緒。上下文切換與模式切換 上下文切換只能發生在核心態中。核心態是 cpu 的一種有特權的模式,在這種模式下只有核心執行並且可以訪問所有記憶體和其他系統資源。其他的程式,如應用程式,在最開始都是執行在使用者...