資料介紹
進(jìn)程調(diào)度依據(jù)
調(diào)度程序運(yùn)行時(shí),要在所有可運(yùn)行狀態(tài)的進(jìn)程中選擇最值得運(yùn)行的進(jìn)程投入運(yùn)行。選擇進(jìn)程的依據(jù)是什么呢?在每個(gè)進(jìn)程的task_strUCt結(jié)構(gòu)中有以下四項(xiàng):policy、priority、counter、rt_priority。這四項(xiàng)是選擇進(jìn)程的依據(jù)。 其中,policy是進(jìn)程的調(diào)度策略,用來(lái)區(qū)分實(shí)時(shí)進(jìn)程和普通進(jìn)程,實(shí)時(shí)進(jìn)程優(yōu)先于普通進(jìn)程運(yùn)行;priority是進(jìn)程(包括實(shí)時(shí)和普通)的靜態(tài)優(yōu)先級(jí);counter是進(jìn)程剩余的時(shí)間片,它的起始值就是priority的值;由于counter在后面計(jì)算一個(gè)處于可運(yùn)行狀態(tài)的進(jìn)程值得運(yùn)行的程度goodness時(shí)起重要作用,因此,counter也可以看作是進(jìn)程的動(dòng)態(tài)優(yōu)先級(jí)。rt_priority是實(shí)時(shí)進(jìn)程特有的,用于實(shí)時(shí)進(jìn)程間的選擇。
Linux用函數(shù)goodness()來(lái)衡量一個(gè)處于可運(yùn)行狀態(tài)的進(jìn)程值得運(yùn)行的程度。該函數(shù)綜合了以上提到的四項(xiàng),還結(jié)合了一些其他的因素,給每個(gè)處于可運(yùn)行狀態(tài)的進(jìn)程賦予一個(gè)權(quán)值(weight),調(diào)度程序以這個(gè)權(quán)值作為選擇進(jìn)程的唯一依據(jù)。關(guān)于goodness()的情況在后面將會(huì)詳細(xì)分析。
進(jìn)程調(diào)度策略
調(diào)度程序運(yùn)行時(shí),要在所有處于可運(yùn)行狀態(tài)的進(jìn)程之中選擇最值得運(yùn)行的進(jìn)程投入運(yùn)行。選擇進(jìn)程的依據(jù)是什么呢?在每個(gè)進(jìn)程的task_struct 結(jié)構(gòu)中有這么四項(xiàng):
policy, priority , counter, rt_priority
這四項(xiàng)就是調(diào)度程序選擇進(jìn)程的依據(jù)。其中,policy是進(jìn)程的調(diào)度策略,用來(lái)區(qū)分兩種進(jìn)程-實(shí)時(shí)和普通;priority是進(jìn)程(實(shí)時(shí)和普通)的優(yōu)先級(jí);counter 是進(jìn)程剩余的時(shí)間片,它的大小完全由priority決定;rt_priority是實(shí)時(shí)優(yōu)先級(jí),這是實(shí)時(shí)進(jìn)程所特有的,用于實(shí)時(shí)進(jìn)程間的選擇。
首先,Linux 根據(jù)policy從整體上區(qū)分實(shí)時(shí)進(jìn)程和普通進(jìn)程,因?yàn)閷?shí)時(shí)進(jìn)程和普通進(jìn)程度調(diào)度是不同的,它們兩者之間,實(shí)時(shí)進(jìn)程應(yīng)該先于普通進(jìn)程而運(yùn)行,然后,對(duì)于同一類型的不同進(jìn)程,采用不同的標(biāo)準(zhǔn)來(lái)選擇進(jìn)程:
對(duì)于普通進(jìn)程,Linux采用動(dòng)態(tài)優(yōu)先調(diào)度,選擇進(jìn)程的依據(jù)就是進(jìn)程counter的大小。進(jìn)程創(chuàng)建時(shí),優(yōu)先級(jí)priority被賦一個(gè)初值,一般為0~70之間的數(shù)字,這個(gè)數(shù)字同時(shí)也是計(jì)數(shù)器counter的初值,就是說(shuō)進(jìn)程創(chuàng)建時(shí)兩者是相等的。字面上看,priority是\“優(yōu)先級(jí)\”、counter是\“計(jì)數(shù)器\”的意思,然而實(shí)際上,它們表達(dá)的是同一個(gè)意思-進(jìn)程的\“時(shí)間片\”。Priority代表分配給該進(jìn)程的時(shí)間片,counter表示該進(jìn)程剩余的時(shí)間片。在進(jìn)程運(yùn)行過(guò)程中,counter不斷減少,而priority保持不變,以便在counter變?yōu)?的時(shí)候(該進(jìn)程用完了所分配的時(shí)間片)對(duì)counter重新賦值。當(dāng)一個(gè)普通進(jìn)程的時(shí)間片用完以后,并不馬上用priority對(duì)counter進(jìn)行賦值,只有所有處于可運(yùn)行狀態(tài)的普通進(jìn)程的時(shí)間片(p-》counter==0)都用完了以后,才用priority對(duì)counter重新賦值,這個(gè)普通進(jìn)程才有了再次被調(diào)度的機(jī)會(huì)。這說(shuō)明,普通進(jìn)程運(yùn)行過(guò)程中,counter的減小給了其它進(jìn)程得以運(yùn)行的機(jī)會(huì),直至counter減為0時(shí)才完全放棄對(duì)CPU的使用,這就相對(duì)于優(yōu)先級(jí)在動(dòng)態(tài)變化,所以稱之為動(dòng)態(tài)優(yōu)先調(diào)度。至于時(shí)間片這個(gè)概念,和其他不同操作系統(tǒng)一樣的,Linux的時(shí)間單位也是\“時(shí)鐘滴答\”,只是不同操作系統(tǒng)對(duì)一個(gè)時(shí)鐘滴答的定義不同而已(Linux為10ms)。進(jìn)程的時(shí)間片就是指多少個(gè)時(shí)鐘滴答,比如,若priority為20,則分配給該進(jìn)程的時(shí)間片就為20個(gè)時(shí)鐘滴答,也就是20*10ms=200ms。Linux中某個(gè)進(jìn)程的調(diào)度策略(policy)、優(yōu)先級(jí)(priority)等可以作為參數(shù)由用戶自己決定,具有相當(dāng)?shù)撵`活性。內(nèi)核創(chuàng)建新進(jìn)程時(shí)分配給進(jìn)程的時(shí)間片缺省為200ms(更準(zhǔn)確的,應(yīng)為210ms),用戶可以通過(guò)系統(tǒng)調(diào)用改變它。
對(duì)于實(shí)時(shí)進(jìn)程,Linux采用了兩種調(diào)度策略,即FIFO(先來(lái)先服務(wù)調(diào)度)和RR(時(shí)間片輪轉(zhuǎn)調(diào)度)。因?yàn)閷?shí)時(shí)進(jìn)程具有一定程度的緊迫性,所以衡量一個(gè)實(shí)時(shí)進(jìn)程是否應(yīng)該運(yùn)行,Linux采用了一個(gè)比較固定的標(biāo)準(zhǔn)。實(shí)時(shí)進(jìn)程的counter只是用來(lái)表示該進(jìn)程的剩余時(shí)間片,并不作為衡量它是否值得運(yùn)行的標(biāo)準(zhǔn)。實(shí)時(shí)進(jìn)程的counter只是用來(lái)表示該進(jìn)程的剩余時(shí)間片,并不作為衡量它是否值得運(yùn)行的標(biāo)準(zhǔn),這和普通進(jìn)程是有區(qū)別的。上面已經(jīng)看到,每個(gè)進(jìn)程有兩個(gè)優(yōu)先級(jí),實(shí)時(shí)優(yōu)先級(jí)就是用來(lái)衡量實(shí)時(shí)進(jìn)程是否值得運(yùn)行的。
這一切看來(lái)比較麻煩,但實(shí)際上Linux中的實(shí)現(xiàn)相當(dāng)簡(jiǎn)單。Linux用函數(shù)goodness()來(lái)衡量一個(gè)處于可運(yùn)行狀態(tài)的進(jìn)程值得運(yùn)行的程度。該函數(shù)綜合了上面提到的各個(gè)方面,給每個(gè)處于可運(yùn)行狀態(tài)的進(jìn)程賦予一個(gè)權(quán)值(weight),調(diào)度程序以這個(gè)權(quán)值作為選擇進(jìn)程的唯一依據(jù)。
Linux根據(jù)policy的值將進(jìn)程總體上分為實(shí)時(shí)進(jìn)程和普通進(jìn)程,提供了三種調(diào)度算法:一種傳統(tǒng)的Unix調(diào)度程序和兩個(gè)由POSIX.1b(原名為POSIX.4)操作系統(tǒng)標(biāo)準(zhǔn)所規(guī)定的\“實(shí)時(shí)\”調(diào)度程序。但這種實(shí)時(shí)只是軟實(shí)時(shí),不滿足諸如中斷等待時(shí)間等硬實(shí)時(shí)要求,只是保證了當(dāng)實(shí)時(shí)進(jìn)程需要時(shí)一定只把CPU分配給實(shí)時(shí)進(jìn)程。
非實(shí)時(shí)進(jìn)程有兩種優(yōu)先級(jí),一種是靜態(tài)優(yōu)先級(jí),另一種是動(dòng)態(tài)優(yōu)先級(jí)。實(shí)時(shí)進(jìn)程又增加了第三種優(yōu)先級(jí),實(shí)時(shí)優(yōu)先級(jí)。優(yōu)先級(jí)是一些簡(jiǎn)單的整數(shù),為了決定應(yīng)該允許哪一個(gè)進(jìn)程使用CPU的資源,用優(yōu)先級(jí)代表相對(duì)權(quán)值-優(yōu)先級(jí)越高,它得到CPU時(shí)間的機(jī)會(huì)也就越大。
靜態(tài)優(yōu)先級(jí)(priority)-不隨時(shí)間而改變,只能由用戶進(jìn)行修改。它指明了在被迫和其他進(jìn)程競(jìng)爭(zhēng)CPU之前,該進(jìn)程所應(yīng)該被允許的時(shí)間片的最大值(但很可能的,在該時(shí)間片耗盡之前,進(jìn)程就被迫交出了CPU)。
動(dòng)態(tài)優(yōu)先級(jí)(counter)-只要進(jìn)程擁有CPU,它就隨著時(shí)間不斷減?。划?dāng)它小于0時(shí),標(biāo)記進(jìn)程重新調(diào)度。它指明了在這個(gè)時(shí)間片中所剩余的時(shí)間量。
實(shí)時(shí)優(yōu)先級(jí)(rt_priority)-指明這個(gè)進(jìn)程自動(dòng)把CPU交給哪一個(gè)其他進(jìn)程;較高權(quán)值的進(jìn)程總是優(yōu)先于較低權(quán)值的進(jìn)程。如果一個(gè)進(jìn)程不是實(shí)時(shí)進(jìn)程,其優(yōu)先級(jí)就是0,所以實(shí)時(shí)進(jìn)程總是優(yōu)先于非實(shí)時(shí)進(jìn)程的(但實(shí)際上,實(shí)時(shí)進(jìn)程也會(huì)主動(dòng)放棄CPU)。
當(dāng)policy分別為以下值時(shí):
1) SCHED_OTHER:這是普通的用戶進(jìn)程,進(jìn)程的缺省類型,采用動(dòng)態(tài)優(yōu)先調(diào)度策略,選擇進(jìn)程的依據(jù)主要是根據(jù)進(jìn)程goodness值的大小。這種進(jìn)程在運(yùn)行時(shí),可以被高goodness值的進(jìn)程搶先。
2) SCHED_FIFO:這是一種實(shí)時(shí)進(jìn)程,遵守POSIX1.b標(biāo)準(zhǔn)的FIFO(先入先出)調(diào)度規(guī)則。它會(huì)一直運(yùn)行,直到有一個(gè)進(jìn)程因I/O阻塞,或者主動(dòng)釋放CPU,或者是CPU被另一個(gè)具有更高rt_priority的實(shí)時(shí)進(jìn)程搶先。在Linux實(shí)現(xiàn)中,SCHED_FIFO進(jìn)程仍然擁有時(shí)間片-只有當(dāng)時(shí)間片用完時(shí)它們才被迫釋放CPU。因此,如同POSIX1.b一樣,這樣的進(jìn)程就象沒(méi)有時(shí)間片(不是采用分時(shí))一樣運(yùn)行。Linux中進(jìn)程仍然保持對(duì)其時(shí)間片的記錄(不修改counter)主要是為了實(shí)現(xiàn)的方便,同時(shí)避免在調(diào)度代碼的關(guān)鍵路徑上出現(xiàn)條件判斷語(yǔ)句 if (?。╟urrent-》policy&SCHED_FIFO)){。..}-要知道,其他大量非FIFO進(jìn)程都需要記錄時(shí)間片,這種多余的檢測(cè)只會(huì)浪費(fèi)CPU資源。(一種優(yōu)化措施,不該將執(zhí)行時(shí)間占10%的代碼的運(yùn)行時(shí)間減少到50%;而是將執(zhí)行時(shí)間占90%的代碼的運(yùn)行時(shí)間減少到95%。0.9+0.1*0.5=0.95》0.1+0.9*0.9=0.91)
3) SCHED_RR:這也是一種實(shí)時(shí)進(jìn)程,遵守POSIX1.b標(biāo)準(zhǔn)的RR(循環(huán)round-robin)調(diào)度規(guī)則。除了時(shí)間片有些不同外,這種策略與SCHED_FIFO類似。當(dāng)SCHED_RR進(jìn)程的時(shí)間片用完后,就被放到SCHED_FIFO和SCHED_RR隊(duì)列的末尾。
只要系統(tǒng)中有一個(gè)實(shí)時(shí)進(jìn)程在運(yùn)行,則任何SCHED_OTHER進(jìn)程都不能在任何CPU運(yùn)行。每個(gè)實(shí)時(shí)進(jìn)程有一個(gè)rt_priority,因此,可以按照rt_priority在所有SCHED_RR進(jìn)程之間分配CPU。其作用與SCHED_OTHER進(jìn)程的priority作用一樣。只有root用戶能夠用系統(tǒng)調(diào)用sched_setscheduler,來(lái)改變當(dāng)前進(jìn)程的類型(sys_nice,sys_setpriority)。
此外,內(nèi)核還定義了SCHED_YIELD,這并不是一種調(diào)度策略,而是截取調(diào)度策略的一個(gè)附加位。如同前面說(shuō)明的一樣,如果有其他進(jìn)程需要CPU,它就提示調(diào)度程序釋放CPU。特別要注意的就是這甚至?xí)饘?shí)時(shí)進(jìn)程把CPU釋放給非實(shí)時(shí)進(jìn)程。
主要的進(jìn)程調(diào)度的函數(shù)分析
真正執(zhí)行調(diào)度的函數(shù)是schedule(void),它選擇一個(gè)最合適的進(jìn)程執(zhí)行,并且真正進(jìn)行上下文切換,使得選中的進(jìn)程得以執(zhí)行。而reschedule_idle(struct task_struct *p)的作用是為進(jìn)程選擇一個(gè)合適的CPU來(lái)執(zhí)行,如果它選中了某個(gè)CPU,則將該CPU上當(dāng)前運(yùn)行進(jìn)程的need_resched標(biāo)志置為1,然后向它發(fā)出一個(gè)重新調(diào)度的處理機(jī)間中斷,使得選中的CPU能夠在中斷處理返回時(shí)執(zhí)行schedule函數(shù),真正調(diào)度進(jìn)程p在CPU上執(zhí)行。在schedule()和reschedule_idle()中調(diào)用了goodness()函數(shù)。goodness()函數(shù)用來(lái)衡量一個(gè)處于可運(yùn)行狀態(tài)的進(jìn)程值得運(yùn)行的程度。此外,在schedule()函數(shù)中還調(diào)用了schedule_tail()函數(shù);在reschedule_idle()函數(shù)中還調(diào)用了reschedule_idle_slow()。這些函數(shù)的實(shí)現(xiàn)對(duì)理解SMP的調(diào)度非常重要,下面一一分析這些函數(shù)。先給出每個(gè)函數(shù)的主要流程圖,然后給出源代碼,并加注釋。
goodness()函數(shù)分析
goodness()函數(shù)計(jì)算一個(gè)處于可運(yùn)行狀態(tài)的進(jìn)程值得運(yùn)行的程度。一個(gè)任務(wù)的goodness是以下因素的函數(shù):正在運(yùn)行的任務(wù)、想要運(yùn)行的任務(wù)、當(dāng)前的CPU。goodness返回下面兩類值中的一個(gè):1000以下或者1000以上。1000或者1000以上的值只能賦給\“實(shí)時(shí)\”進(jìn)程,從0到999的值只能賦給普通進(jìn)程。實(shí)際上,在單處理器情況下,普通進(jìn)程的goodness值只使用這個(gè)范圍底部的一部分,從0到41。在SMP情況下,SMP模式會(huì)優(yōu)先照顧等待同一個(gè)處理器的進(jìn)程。不過(guò),不管是UP還是SMP,實(shí)時(shí)進(jìn)程的goodness值的范圍是從1001到1099。
goodness()函數(shù)其實(shí)是不會(huì)返回-1000的,也不會(huì)返回其他負(fù)值。由于idle進(jìn)程的counter值為負(fù),所以如果使用idle進(jìn)程作為參數(shù)調(diào)用goodness,就會(huì)返回負(fù)值,但這是不會(huì)發(fā)生的。
?
調(diào)度程序運(yùn)行時(shí),要在所有可運(yùn)行狀態(tài)的進(jìn)程中選擇最值得運(yùn)行的進(jìn)程投入運(yùn)行。選擇進(jìn)程的依據(jù)是什么呢?在每個(gè)進(jìn)程的task_strUCt結(jié)構(gòu)中有以下四項(xiàng):policy、priority、counter、rt_priority。這四項(xiàng)是選擇進(jìn)程的依據(jù)。 其中,policy是進(jìn)程的調(diào)度策略,用來(lái)區(qū)分實(shí)時(shí)進(jìn)程和普通進(jìn)程,實(shí)時(shí)進(jìn)程優(yōu)先于普通進(jìn)程運(yùn)行;priority是進(jìn)程(包括實(shí)時(shí)和普通)的靜態(tài)優(yōu)先級(jí);counter是進(jìn)程剩余的時(shí)間片,它的起始值就是priority的值;由于counter在后面計(jì)算一個(gè)處于可運(yùn)行狀態(tài)的進(jìn)程值得運(yùn)行的程度goodness時(shí)起重要作用,因此,counter也可以看作是進(jìn)程的動(dòng)態(tài)優(yōu)先級(jí)。rt_priority是實(shí)時(shí)進(jìn)程特有的,用于實(shí)時(shí)進(jìn)程間的選擇。
Linux用函數(shù)goodness()來(lái)衡量一個(gè)處于可運(yùn)行狀態(tài)的進(jìn)程值得運(yùn)行的程度。該函數(shù)綜合了以上提到的四項(xiàng),還結(jié)合了一些其他的因素,給每個(gè)處于可運(yùn)行狀態(tài)的進(jìn)程賦予一個(gè)權(quán)值(weight),調(diào)度程序以這個(gè)權(quán)值作為選擇進(jìn)程的唯一依據(jù)。關(guān)于goodness()的情況在后面將會(huì)詳細(xì)分析。
進(jìn)程調(diào)度策略
調(diào)度程序運(yùn)行時(shí),要在所有處于可運(yùn)行狀態(tài)的進(jìn)程之中選擇最值得運(yùn)行的進(jìn)程投入運(yùn)行。選擇進(jìn)程的依據(jù)是什么呢?在每個(gè)進(jìn)程的task_struct 結(jié)構(gòu)中有這么四項(xiàng):
policy, priority , counter, rt_priority
這四項(xiàng)就是調(diào)度程序選擇進(jìn)程的依據(jù)。其中,policy是進(jìn)程的調(diào)度策略,用來(lái)區(qū)分兩種進(jìn)程-實(shí)時(shí)和普通;priority是進(jìn)程(實(shí)時(shí)和普通)的優(yōu)先級(jí);counter 是進(jìn)程剩余的時(shí)間片,它的大小完全由priority決定;rt_priority是實(shí)時(shí)優(yōu)先級(jí),這是實(shí)時(shí)進(jìn)程所特有的,用于實(shí)時(shí)進(jìn)程間的選擇。
首先,Linux 根據(jù)policy從整體上區(qū)分實(shí)時(shí)進(jìn)程和普通進(jìn)程,因?yàn)閷?shí)時(shí)進(jìn)程和普通進(jìn)程度調(diào)度是不同的,它們兩者之間,實(shí)時(shí)進(jìn)程應(yīng)該先于普通進(jìn)程而運(yùn)行,然后,對(duì)于同一類型的不同進(jìn)程,采用不同的標(biāo)準(zhǔn)來(lái)選擇進(jìn)程:
對(duì)于普通進(jìn)程,Linux采用動(dòng)態(tài)優(yōu)先調(diào)度,選擇進(jìn)程的依據(jù)就是進(jìn)程counter的大小。進(jìn)程創(chuàng)建時(shí),優(yōu)先級(jí)priority被賦一個(gè)初值,一般為0~70之間的數(shù)字,這個(gè)數(shù)字同時(shí)也是計(jì)數(shù)器counter的初值,就是說(shuō)進(jìn)程創(chuàng)建時(shí)兩者是相等的。字面上看,priority是\“優(yōu)先級(jí)\”、counter是\“計(jì)數(shù)器\”的意思,然而實(shí)際上,它們表達(dá)的是同一個(gè)意思-進(jìn)程的\“時(shí)間片\”。Priority代表分配給該進(jìn)程的時(shí)間片,counter表示該進(jìn)程剩余的時(shí)間片。在進(jìn)程運(yùn)行過(guò)程中,counter不斷減少,而priority保持不變,以便在counter變?yōu)?的時(shí)候(該進(jìn)程用完了所分配的時(shí)間片)對(duì)counter重新賦值。當(dāng)一個(gè)普通進(jìn)程的時(shí)間片用完以后,并不馬上用priority對(duì)counter進(jìn)行賦值,只有所有處于可運(yùn)行狀態(tài)的普通進(jìn)程的時(shí)間片(p-》counter==0)都用完了以后,才用priority對(duì)counter重新賦值,這個(gè)普通進(jìn)程才有了再次被調(diào)度的機(jī)會(huì)。這說(shuō)明,普通進(jìn)程運(yùn)行過(guò)程中,counter的減小給了其它進(jìn)程得以運(yùn)行的機(jī)會(huì),直至counter減為0時(shí)才完全放棄對(duì)CPU的使用,這就相對(duì)于優(yōu)先級(jí)在動(dòng)態(tài)變化,所以稱之為動(dòng)態(tài)優(yōu)先調(diào)度。至于時(shí)間片這個(gè)概念,和其他不同操作系統(tǒng)一樣的,Linux的時(shí)間單位也是\“時(shí)鐘滴答\”,只是不同操作系統(tǒng)對(duì)一個(gè)時(shí)鐘滴答的定義不同而已(Linux為10ms)。進(jìn)程的時(shí)間片就是指多少個(gè)時(shí)鐘滴答,比如,若priority為20,則分配給該進(jìn)程的時(shí)間片就為20個(gè)時(shí)鐘滴答,也就是20*10ms=200ms。Linux中某個(gè)進(jìn)程的調(diào)度策略(policy)、優(yōu)先級(jí)(priority)等可以作為參數(shù)由用戶自己決定,具有相當(dāng)?shù)撵`活性。內(nèi)核創(chuàng)建新進(jìn)程時(shí)分配給進(jìn)程的時(shí)間片缺省為200ms(更準(zhǔn)確的,應(yīng)為210ms),用戶可以通過(guò)系統(tǒng)調(diào)用改變它。
對(duì)于實(shí)時(shí)進(jìn)程,Linux采用了兩種調(diào)度策略,即FIFO(先來(lái)先服務(wù)調(diào)度)和RR(時(shí)間片輪轉(zhuǎn)調(diào)度)。因?yàn)閷?shí)時(shí)進(jìn)程具有一定程度的緊迫性,所以衡量一個(gè)實(shí)時(shí)進(jìn)程是否應(yīng)該運(yùn)行,Linux采用了一個(gè)比較固定的標(biāo)準(zhǔn)。實(shí)時(shí)進(jìn)程的counter只是用來(lái)表示該進(jìn)程的剩余時(shí)間片,并不作為衡量它是否值得運(yùn)行的標(biāo)準(zhǔn)。實(shí)時(shí)進(jìn)程的counter只是用來(lái)表示該進(jìn)程的剩余時(shí)間片,并不作為衡量它是否值得運(yùn)行的標(biāo)準(zhǔn),這和普通進(jìn)程是有區(qū)別的。上面已經(jīng)看到,每個(gè)進(jìn)程有兩個(gè)優(yōu)先級(jí),實(shí)時(shí)優(yōu)先級(jí)就是用來(lái)衡量實(shí)時(shí)進(jìn)程是否值得運(yùn)行的。
這一切看來(lái)比較麻煩,但實(shí)際上Linux中的實(shí)現(xiàn)相當(dāng)簡(jiǎn)單。Linux用函數(shù)goodness()來(lái)衡量一個(gè)處于可運(yùn)行狀態(tài)的進(jìn)程值得運(yùn)行的程度。該函數(shù)綜合了上面提到的各個(gè)方面,給每個(gè)處于可運(yùn)行狀態(tài)的進(jìn)程賦予一個(gè)權(quán)值(weight),調(diào)度程序以這個(gè)權(quán)值作為選擇進(jìn)程的唯一依據(jù)。
Linux根據(jù)policy的值將進(jìn)程總體上分為實(shí)時(shí)進(jìn)程和普通進(jìn)程,提供了三種調(diào)度算法:一種傳統(tǒng)的Unix調(diào)度程序和兩個(gè)由POSIX.1b(原名為POSIX.4)操作系統(tǒng)標(biāo)準(zhǔn)所規(guī)定的\“實(shí)時(shí)\”調(diào)度程序。但這種實(shí)時(shí)只是軟實(shí)時(shí),不滿足諸如中斷等待時(shí)間等硬實(shí)時(shí)要求,只是保證了當(dāng)實(shí)時(shí)進(jìn)程需要時(shí)一定只把CPU分配給實(shí)時(shí)進(jìn)程。
非實(shí)時(shí)進(jìn)程有兩種優(yōu)先級(jí),一種是靜態(tài)優(yōu)先級(jí),另一種是動(dòng)態(tài)優(yōu)先級(jí)。實(shí)時(shí)進(jìn)程又增加了第三種優(yōu)先級(jí),實(shí)時(shí)優(yōu)先級(jí)。優(yōu)先級(jí)是一些簡(jiǎn)單的整數(shù),為了決定應(yīng)該允許哪一個(gè)進(jìn)程使用CPU的資源,用優(yōu)先級(jí)代表相對(duì)權(quán)值-優(yōu)先級(jí)越高,它得到CPU時(shí)間的機(jī)會(huì)也就越大。
靜態(tài)優(yōu)先級(jí)(priority)-不隨時(shí)間而改變,只能由用戶進(jìn)行修改。它指明了在被迫和其他進(jìn)程競(jìng)爭(zhēng)CPU之前,該進(jìn)程所應(yīng)該被允許的時(shí)間片的最大值(但很可能的,在該時(shí)間片耗盡之前,進(jìn)程就被迫交出了CPU)。
動(dòng)態(tài)優(yōu)先級(jí)(counter)-只要進(jìn)程擁有CPU,它就隨著時(shí)間不斷減?。划?dāng)它小于0時(shí),標(biāo)記進(jìn)程重新調(diào)度。它指明了在這個(gè)時(shí)間片中所剩余的時(shí)間量。
實(shí)時(shí)優(yōu)先級(jí)(rt_priority)-指明這個(gè)進(jìn)程自動(dòng)把CPU交給哪一個(gè)其他進(jìn)程;較高權(quán)值的進(jìn)程總是優(yōu)先于較低權(quán)值的進(jìn)程。如果一個(gè)進(jìn)程不是實(shí)時(shí)進(jìn)程,其優(yōu)先級(jí)就是0,所以實(shí)時(shí)進(jìn)程總是優(yōu)先于非實(shí)時(shí)進(jìn)程的(但實(shí)際上,實(shí)時(shí)進(jìn)程也會(huì)主動(dòng)放棄CPU)。
當(dāng)policy分別為以下值時(shí):
1) SCHED_OTHER:這是普通的用戶進(jìn)程,進(jìn)程的缺省類型,采用動(dòng)態(tài)優(yōu)先調(diào)度策略,選擇進(jìn)程的依據(jù)主要是根據(jù)進(jìn)程goodness值的大小。這種進(jìn)程在運(yùn)行時(shí),可以被高goodness值的進(jìn)程搶先。
2) SCHED_FIFO:這是一種實(shí)時(shí)進(jìn)程,遵守POSIX1.b標(biāo)準(zhǔn)的FIFO(先入先出)調(diào)度規(guī)則。它會(huì)一直運(yùn)行,直到有一個(gè)進(jìn)程因I/O阻塞,或者主動(dòng)釋放CPU,或者是CPU被另一個(gè)具有更高rt_priority的實(shí)時(shí)進(jìn)程搶先。在Linux實(shí)現(xiàn)中,SCHED_FIFO進(jìn)程仍然擁有時(shí)間片-只有當(dāng)時(shí)間片用完時(shí)它們才被迫釋放CPU。因此,如同POSIX1.b一樣,這樣的進(jìn)程就象沒(méi)有時(shí)間片(不是采用分時(shí))一樣運(yùn)行。Linux中進(jìn)程仍然保持對(duì)其時(shí)間片的記錄(不修改counter)主要是為了實(shí)現(xiàn)的方便,同時(shí)避免在調(diào)度代碼的關(guān)鍵路徑上出現(xiàn)條件判斷語(yǔ)句 if (?。╟urrent-》policy&SCHED_FIFO)){。..}-要知道,其他大量非FIFO進(jìn)程都需要記錄時(shí)間片,這種多余的檢測(cè)只會(huì)浪費(fèi)CPU資源。(一種優(yōu)化措施,不該將執(zhí)行時(shí)間占10%的代碼的運(yùn)行時(shí)間減少到50%;而是將執(zhí)行時(shí)間占90%的代碼的運(yùn)行時(shí)間減少到95%。0.9+0.1*0.5=0.95》0.1+0.9*0.9=0.91)
3) SCHED_RR:這也是一種實(shí)時(shí)進(jìn)程,遵守POSIX1.b標(biāo)準(zhǔn)的RR(循環(huán)round-robin)調(diào)度規(guī)則。除了時(shí)間片有些不同外,這種策略與SCHED_FIFO類似。當(dāng)SCHED_RR進(jìn)程的時(shí)間片用完后,就被放到SCHED_FIFO和SCHED_RR隊(duì)列的末尾。
只要系統(tǒng)中有一個(gè)實(shí)時(shí)進(jìn)程在運(yùn)行,則任何SCHED_OTHER進(jìn)程都不能在任何CPU運(yùn)行。每個(gè)實(shí)時(shí)進(jìn)程有一個(gè)rt_priority,因此,可以按照rt_priority在所有SCHED_RR進(jìn)程之間分配CPU。其作用與SCHED_OTHER進(jìn)程的priority作用一樣。只有root用戶能夠用系統(tǒng)調(diào)用sched_setscheduler,來(lái)改變當(dāng)前進(jìn)程的類型(sys_nice,sys_setpriority)。
此外,內(nèi)核還定義了SCHED_YIELD,這并不是一種調(diào)度策略,而是截取調(diào)度策略的一個(gè)附加位。如同前面說(shuō)明的一樣,如果有其他進(jìn)程需要CPU,它就提示調(diào)度程序釋放CPU。特別要注意的就是這甚至?xí)饘?shí)時(shí)進(jìn)程把CPU釋放給非實(shí)時(shí)進(jìn)程。
主要的進(jìn)程調(diào)度的函數(shù)分析
真正執(zhí)行調(diào)度的函數(shù)是schedule(void),它選擇一個(gè)最合適的進(jìn)程執(zhí)行,并且真正進(jìn)行上下文切換,使得選中的進(jìn)程得以執(zhí)行。而reschedule_idle(struct task_struct *p)的作用是為進(jìn)程選擇一個(gè)合適的CPU來(lái)執(zhí)行,如果它選中了某個(gè)CPU,則將該CPU上當(dāng)前運(yùn)行進(jìn)程的need_resched標(biāo)志置為1,然后向它發(fā)出一個(gè)重新調(diào)度的處理機(jī)間中斷,使得選中的CPU能夠在中斷處理返回時(shí)執(zhí)行schedule函數(shù),真正調(diào)度進(jìn)程p在CPU上執(zhí)行。在schedule()和reschedule_idle()中調(diào)用了goodness()函數(shù)。goodness()函數(shù)用來(lái)衡量一個(gè)處于可運(yùn)行狀態(tài)的進(jìn)程值得運(yùn)行的程度。此外,在schedule()函數(shù)中還調(diào)用了schedule_tail()函數(shù);在reschedule_idle()函數(shù)中還調(diào)用了reschedule_idle_slow()。這些函數(shù)的實(shí)現(xiàn)對(duì)理解SMP的調(diào)度非常重要,下面一一分析這些函數(shù)。先給出每個(gè)函數(shù)的主要流程圖,然后給出源代碼,并加注釋。
goodness()函數(shù)分析
goodness()函數(shù)計(jì)算一個(gè)處于可運(yùn)行狀態(tài)的進(jìn)程值得運(yùn)行的程度。一個(gè)任務(wù)的goodness是以下因素的函數(shù):正在運(yùn)行的任務(wù)、想要運(yùn)行的任務(wù)、當(dāng)前的CPU。goodness返回下面兩類值中的一個(gè):1000以下或者1000以上。1000或者1000以上的值只能賦給\“實(shí)時(shí)\”進(jìn)程,從0到999的值只能賦給普通進(jìn)程。實(shí)際上,在單處理器情況下,普通進(jìn)程的goodness值只使用這個(gè)范圍底部的一部分,從0到41。在SMP情況下,SMP模式會(huì)優(yōu)先照顧等待同一個(gè)處理器的進(jìn)程。不過(guò),不管是UP還是SMP,實(shí)時(shí)進(jìn)程的goodness值的范圍是從1001到1099。
goodness()函數(shù)其實(shí)是不會(huì)返回-1000的,也不會(huì)返回其他負(fù)值。由于idle進(jìn)程的counter值為負(fù),所以如果使用idle進(jìn)程作為參數(shù)調(diào)用goodness,就會(huì)返回負(fù)值,但這是不會(huì)發(fā)生的。
?
下載該資料的人也在下載
下載該資料的人還在閱讀
更多 >
- linux嵌入式系統(tǒng)算法,嵌入式Linux操作系統(tǒng)調(diào)度算法研究
- 嵌入式linux查看服務(wù)進(jìn)程,通過(guò)proc查看進(jìn)程資源
- Linux內(nèi)核進(jìn)程調(diào)度schedule深入理解的詳細(xì)資料說(shuō)明 5次下載
- 關(guān)于進(jìn)程與線程的解析PDF文件資料
- Linux的內(nèi)核結(jié)構(gòu)詳細(xì)說(shuō)明 16次下載
- 嵌入式Linux與物聯(lián)網(wǎng)軟件開(kāi)發(fā)C語(yǔ)言內(nèi)核深度解析書籍的介紹
- Linux的調(diào)度類型和調(diào)度器的詳細(xì)資料說(shuō)明
- linux進(jìn)程的深入理解 2次下載
- uClinux進(jìn)程調(diào)度器的實(shí)現(xiàn)分析 0次下載
- Linux守護(hù)進(jìn)程詳解 0次下載
- 分布式系統(tǒng)進(jìn)程調(diào)度方法研究
- Linux源碼分析系列的進(jìn)程 32次下載
- Linux 2.6進(jìn)程調(diào)度
- linux處理機(jī)調(diào)度與死鎖 0次下載
- Linux進(jìn)程管理 0次下載
- Linux用戶身份與進(jìn)程權(quán)限詳解 403次閱讀
- Linux中進(jìn)程、線程和協(xié)程的基礎(chǔ)概念 933次閱讀
- 如何在Linux使用ps/pstree/top命令查看進(jìn)程 1871次閱讀
- 一文深入理解操作系統(tǒng)的進(jìn)程調(diào)度 2480次閱讀
- 一文了解Linux調(diào)度器開(kāi)放給用戶空間的接口 946次閱讀
- Linux:測(cè)試進(jìn)程占用的虛擬內(nèi)存大小 2904次閱讀
- 虛擬機(jī):linux 進(jìn)程的最大線程個(gè)數(shù) 2782次閱讀
- Linux進(jìn)程調(diào)度時(shí)機(jī)概念分析 2812次閱讀
- 嵌入式Linux中進(jìn)程調(diào)度怎樣來(lái)解析 730次閱讀
- Linux調(diào)度器中的PELT(Per-Entity Load Tracking) 4391次閱讀
- Linux進(jìn)程管理:什么是進(jìn)程?進(jìn)程的生命周期 8034次閱讀
- 如何解決Linux進(jìn)程調(diào)度優(yōu)先級(jí)數(shù)字混亂的問(wèn)題?詳細(xì)實(shí)例分析 3482次閱讀
- Linux內(nèi)核的發(fā)展簡(jiǎn)史與系統(tǒng)層次結(jié)構(gòu) 7318次閱讀
- Linux內(nèi)核的DL調(diào)度器的細(xì)節(jié)和怎么樣使用DL調(diào)度器? 5536次閱讀
- 基于Linux進(jìn)程管理的詳細(xì)剖析 3756次閱讀
下載排行
本周
- 1TC358743XBG評(píng)估板參考手冊(cè)
- 1.36 MB | 330次下載 | 免費(fèi)
- 2開(kāi)關(guān)電源基礎(chǔ)知識(shí)
- 5.73 MB | 6次下載 | 免費(fèi)
- 3100W短波放大電路圖
- 0.05 MB | 4次下載 | 3 積分
- 4嵌入式linux-聊天程序設(shè)計(jì)
- 0.60 MB | 3次下載 | 免費(fèi)
- 5基于FPGA的光纖通信系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)
- 0.61 MB | 2次下載 | 免費(fèi)
- 6基于FPGA的C8051F單片機(jī)開(kāi)發(fā)板設(shè)計(jì)
- 0.70 MB | 2次下載 | 免費(fèi)
- 751單片機(jī)窗簾控制器仿真程序
- 1.93 MB | 2次下載 | 免費(fèi)
- 8基于51單片機(jī)的RGB調(diào)色燈程序仿真
- 0.86 MB | 2次下載 | 免費(fèi)
本月
- 1OrCAD10.5下載OrCAD10.5中文版軟件
- 0.00 MB | 234315次下載 | 免費(fèi)
- 2555集成電路應(yīng)用800例(新編版)
- 0.00 MB | 33564次下載 | 免費(fèi)
- 3接口電路圖大全
- 未知 | 30323次下載 | 免費(fèi)
- 4開(kāi)關(guān)電源設(shè)計(jì)實(shí)例指南
- 未知 | 21548次下載 | 免費(fèi)
- 5電氣工程師手冊(cè)免費(fèi)下載(新編第二版pdf電子書)
- 0.00 MB | 15349次下載 | 免費(fèi)
- 6數(shù)字電路基礎(chǔ)pdf(下載)
- 未知 | 13750次下載 | 免費(fèi)
- 7電子制作實(shí)例集錦 下載
- 未知 | 8113次下載 | 免費(fèi)
- 8《LED驅(qū)動(dòng)電路設(shè)計(jì)》 溫德?tīng)栔?/a>
- 0.00 MB | 6653次下載 | 免費(fèi)
總榜
- 1matlab軟件下載入口
- 未知 | 935054次下載 | 免費(fèi)
- 2protel99se軟件下載(可英文版轉(zhuǎn)中文版)
- 78.1 MB | 537796次下載 | 免費(fèi)
- 3MATLAB 7.1 下載 (含軟件介紹)
- 未知 | 420026次下載 | 免費(fèi)
- 4OrCAD10.5下載OrCAD10.5中文版軟件
- 0.00 MB | 234315次下載 | 免費(fèi)
- 5Altium DXP2002下載入口
- 未知 | 233046次下載 | 免費(fèi)
- 6電路仿真軟件multisim 10.0免費(fèi)下載
- 340992 | 191185次下載 | 免費(fèi)
- 7十天學(xué)會(huì)AVR單片機(jī)與C語(yǔ)言視頻教程 下載
- 158M | 183278次下載 | 免費(fèi)
- 8proe5.0野火版下載(中文版免費(fèi)下載)
- 未知 | 138040次下載 | 免費(fèi)
評(píng)論