Linux任務(wù)調(diào)度的時(shí)機(jī)
linux進(jìn)程的調(diào)度時(shí)機(jī)大致分為兩種情況: 一種是進(jìn)程自愿調(diào)度;另一種是發(fā)生強(qiáng)制性調(diào)度。 首先,自愿的調(diào)度隨時(shí)都可以進(jìn)行。在內(nèi)核空間中,進(jìn)程可以通過schedule()啟動(dòng)一次調(diào)度;在用戶空間中,可以通過系統(tǒng)調(diào)用pause()達(dá)到同樣的目的。如果要為自愿的暫停行為加上時(shí)間限制,在內(nèi)核中使用schedule_time(),而在用戶空間則使用nanosleep()系統(tǒng)調(diào)用。
linux中,強(qiáng)制性的調(diào)度發(fā)生在每次從系統(tǒng)調(diào)用返回的前夕,以及每次中斷或異常處理返回用戶空間的前夕。應(yīng)注意的是,從內(nèi)核態(tài)返回到用戶態(tài)是進(jìn)程調(diào)度發(fā)生的必要條件,而不是充分條件,還要取決于當(dāng)進(jìn)程task_struct結(jié)構(gòu)中的need_resched是否為1。
從進(jìn)程調(diào)度的時(shí)機(jī)可以看出,內(nèi)核的調(diào)度方式為“有條件的剝奪方式”。當(dāng)進(jìn)程在用戶空間運(yùn)行,不管自愿不自愿,一旦有必要比如時(shí)間片用完,內(nèi)核就可以暫時(shí)剝奪其運(yùn)行而調(diào)度其他進(jìn)程運(yùn)行。而進(jìn)程一旦進(jìn)入內(nèi)核空間,即進(jìn)入核心態(tài)時(shí),盡管知道應(yīng)該要調(diào)度了,但實(shí)際上卻不會(huì)發(fā)生,一直要到該進(jìn)程返回到用戶空間前夕才能剝奪其運(yùn)行。
Linux任務(wù)調(diào)度策略
Linux支持SCHED_FIFO、SCHED_RR和SCHED_OTHER的調(diào)度策略。
linux用函數(shù)goodness()統(tǒng)一計(jì)算進(jìn)程(包括普通進(jìn)程和實(shí)時(shí)進(jìn)程)的優(yōu)先級(jí)權(quán)值,該權(quán)值衡量一個(gè)處于可運(yùn)行狀態(tài)的進(jìn)程值得運(yùn)行的程度,權(quán)值越大,進(jìn)程優(yōu)先級(jí)越高。 每個(gè)進(jìn)程的task_struct結(jié)構(gòu)中,與goodness()計(jì)算權(quán)值相關(guān)的域有以下四項(xiàng):policy、nice(2.2版內(nèi)核該項(xiàng)為priority)、counter、rt_priority。其中,policy是進(jìn)程的調(diào)度策略,其可用來區(qū)分實(shí)時(shí)進(jìn)程和普通進(jìn)程,實(shí)時(shí)進(jìn)程優(yōu)先于普通進(jìn)程運(yùn)行。nice從最初的UNIX沿用而來,表示進(jìn)程的靜態(tài)負(fù)向優(yōu)先級(jí),其取值范圍為19~-20,以-20優(yōu)先級(jí)最高。counter表示進(jìn)程剩余的時(shí)間片計(jì)數(shù)值,由于counter在計(jì)算goodness()時(shí)起重要作用,因此,counter也可以看作是進(jìn)程的動(dòng)態(tài)優(yōu)先級(jí)。rt_priority是實(shí)時(shí)進(jìn)程特有的,表示實(shí)時(shí)優(yōu)先級(jí)。
首先,linux根據(jù)調(diào)度策略policy從整體上區(qū)分實(shí)時(shí)進(jìn)程和普通進(jìn)程。對(duì)于policy為SCHED_OTHER的普通進(jìn)程,linux采用動(dòng)態(tài)優(yōu)先級(jí)調(diào),其優(yōu)先級(jí)權(quán)值取決于(20-nice)和進(jìn)程當(dāng)前的剩余時(shí)間片計(jì)數(shù)counter之和。進(jìn)程創(chuàng)建時(shí),子進(jìn)程繼承父進(jìn)程的nice值,而父進(jìn)程的counter值則被分為二半,子進(jìn)程和父進(jìn)程各得一半。時(shí)間片計(jì)數(shù)器每次清零后由(20-nice)經(jīng)過換算重新賦值。字面上看,nice是“優(yōu)先級(jí)”、counter是“計(jì)數(shù)器”的意思,然而實(shí)際上,它們表達(dá)的是同個(gè)意思:nice決定了分配給該進(jìn)程的時(shí)間片計(jì)數(shù),nice優(yōu)先級(jí)越高的進(jìn)程分到的時(shí)間片越長,用戶通過系統(tǒng)調(diào)用nice()或setpriority()改變進(jìn)程靜態(tài)優(yōu)先級(jí)nice值的同時(shí),也改變了該進(jìn)程的時(shí)間片長度;counter表示該進(jìn)程剩余的時(shí)間片計(jì)數(shù)值,而nice和counter綜合起來又決定進(jìn)程可運(yùn)行的優(yōu)先級(jí)權(quán)值。在進(jìn)程運(yùn)行過程中,counter不斷減少,而nice保持相對(duì)不變;當(dāng)一個(gè)普通進(jìn)程的時(shí)間片用完以后,并不馬上根據(jù)nice對(duì)counter進(jìn)行重新賦值,只有所有處于可運(yùn)行狀態(tài)的普通進(jìn)程的時(shí)間片都用完了以后(counter等于0),才根據(jù)nice對(duì)counter重新賦值,這個(gè)普通進(jìn)程才有了再次被調(diào)度的機(jī)會(huì)。這說明,普通進(jìn)程運(yùn)行過程中,counter的減小給了其它進(jìn)程得以運(yùn)行的機(jī)會(huì),直至counter減為0時(shí)才完全放棄對(duì)CPU的使用,這就相當(dāng)于優(yōu)先級(jí)在動(dòng)態(tài)變化,所以稱之為動(dòng)態(tài)優(yōu)先調(diào)度。
對(duì)于實(shí)時(shí)進(jìn)程,linux采用了兩種調(diào)度策略,即SCHED_FIFO(先來先服務(wù)調(diào)度)和SCHED_RR(時(shí)間片輪轉(zhuǎn)調(diào)度)。因?yàn)閷?shí)時(shí)進(jìn)程具有一定程度的緊迫性,所以衡量一個(gè)實(shí)時(shí)進(jìn)程是否應(yīng)該運(yùn)行,采用了一個(gè)比較固定的標(biāo)準(zhǔn),即參考rt_priority的值。用函數(shù)goodness()計(jì)算進(jìn)程的優(yōu)先級(jí)權(quán)值時(shí),對(duì)實(shí)時(shí)進(jìn)程是在1000的基礎(chǔ)上加上rt_priority的值,而非實(shí)時(shí)進(jìn)程的動(dòng)態(tài)優(yōu)先級(jí)綜合起來的調(diào)度權(quán)值始終在以下,所以goodness()的優(yōu)先級(jí)權(quán)值計(jì)算方法確保實(shí)時(shí)進(jìn)程的調(diào)度權(quán)值始終比所有的非實(shí)時(shí)進(jìn)程都要大,這就保證了實(shí)時(shí)進(jìn)程的優(yōu)先運(yùn)行。實(shí)時(shí)進(jìn)程的counter與nice都與其優(yōu)先級(jí)權(quán)值無關(guān),這和普通進(jìn)程是有區(qū)別的,實(shí)時(shí)進(jìn)程task_struct中的counter和nice只與SCHED_RR調(diào)度策略進(jìn)程的時(shí)間片計(jì)數(shù)相關(guān);而對(duì)于SCHED_FIFO調(diào)度策略的實(shí)時(shí)進(jìn)程沒有調(diào)度的參考意義。聯(lián)系客服