本文分享了程序員面試關(guān)于 Linux 內(nèi)核實時系統(tǒng)的冷知識。希望能讓大家增長一點知識。
背景知識
Linux的調(diào)度策略包括SCHED_FIFO and SCHED_RR 和SCHED_OTHER
SCHED_FIFO
(Round-robin線程調(diào)度策略)和SCHED_RR
是“實時”策略。實現(xiàn)POSIX
標準規(guī)定的固定優(yōu)先級實時調(diào)度(fixed-priority real-time scheduling)。按照這些策略的任務會搶占其他所有任務。因為是搶占,如果它們不釋放CPU,所以很容易使得某些低級別的任務得不到執(zhí)行。
SCHED_FIFO
和SCHED_RR
之間的區(qū)別在于:在相同優(yōu)先級的任務中,SCHED_RR
執(zhí)行round-robin
分配,每個任務都得到相同的cpu時間片策略。而SCHED_FIFO
需要任務主動放棄cpu時間片。
SCHED_OTHER
是常見的循環(huán)式分時調(diào)度策略,該調(diào)度策略根據(jù)系統(tǒng)中運行的其他任務為某個時間的調(diào)度任務。
SCHED_RR和SCHED_FIFO的問題:
紅帽企業(yè)版Linux
實時版中的兩種實時調(diào)度策略具有一個主要特征:直到被更高優(yōu)先級的線程搶占或直到它們“等待”(sleep/休眠或執(zhí)行I/O)線程會一直運行。如果是SCHED_RR
,在SCHED_RR
優(yōu)先級相同的線程中,操作系統(tǒng)可能會搶占一個線程,讓另一個線程得以執(zhí)行。
POSIX
規(guī)范沒有規(guī)定允許低優(yōu)先級線程獲得任何CPU時間的策略。
實時線程的這種特性意味著編寫一個霸占100%的CPU的應用程序非常容易。乍一看,好像榨干了服務器是個不錯的想法,但實際上,它引起了操作系統(tǒng)的許多問題。操作系統(tǒng)負責管理系統(tǒng)范圍的資源和按CPU的資源,并且必須定期檢查描述這些資源的數(shù)據(jù)結(jié)構(gòu),并對其執(zhí)行內(nèi)部管理活動。如果內(nèi)核被SCHED_FIFO
線程壟斷,則它無法執(zhí)行內(nèi)務處理任務,最終整個系統(tǒng)將變得不穩(wěn)定,從而可能導致崩潰。
中斷處理程序以具有SCHED_FIFO
優(yōu)先級的線程(默認值:50)運行。具有或策略高于中斷處理程序線程的cpuxiao hao x
線程可能會阻止中斷處理程序運行,并導致程序等待那些由中斷發(fā)出的數(shù)據(jù),從而使該程序餓死并失敗。
紅帽/CentOS的特殊策略/實時節(jié)流機制
在紅帽企業(yè)版實時系統(tǒng)內(nèi)核中,有個實時節(jié)流機制/SCHED_FIFOSCHED_RR
限制實時調(diào)度的調(diào)度策略(real-time scheduler throttling)。
紅帽企業(yè)版實時Linux內(nèi)核帶有一種保護機制,該機制使系統(tǒng)管理員可以分配資源配額以供實時任務使用。這個配額機制引入,算是一個保護機制。
這個機制用/proc
文件系統(tǒng)中的兩個參數(shù)控制。
/proc/sys/kernel/sched_rt_period_us
定義時間周期,以微秒為單位,相當于100%的CPU資源帶寬。默認值為1,000,000μs(1秒)。謹慎更改該時間段,時間段過長或太小都將危險。
/proc/sys/kernel/sched_rt_runtime_us
定義所有實時任務可用的總帶寬。默認值為950,000μs(0.95 s),即CPU帶寬的95%。將該值設置為-1意味著實時任務最多可能占用100%的CPU時間。僅當在特殊場景實時任務經(jīng)過精心設計并且沒有明顯的隱患(比如沒有無限制的輪詢循環(huán))時,才可以這樣配置。
對于實時調(diào)節(jié)機制的默認值定義的CPU時間的95%,意思是95%的cpu時間片可以通過實時任務中使用。剩余的5%將用于非實時任務(在SCHED_OTHER
類似的調(diào)度策略下運行的任務)。而且需要注意,如果單個實時任務占用了95%的CPU時隙,則該CPU上剩余的實時任務將不會運行。剩下的5%的CPU時間僅由非實時任務使用。
默認值的設置帶來兩個好處:流氓實時任務不會通過不允許非實時任務運行來鎖定系統(tǒng),另一方面,實時任務最多具有95%的CPU他們的可用時間,可能會最大化效能。
聰明做法RT_RUNTIME_GREED
盡管SCHED_FIFOSCHED_RR/實時節(jié)流機制
的工作原理是避免實時任務可能導致系統(tǒng)掛起,但是高級用戶可能希望在沒有非實時任務匱乏的情況下允許實時任務繼續(xù)運行, 避免系統(tǒng)閑置。
啟用后,此功能會在限制實時任務之前檢查非實時任務是否餓死。如果實時任務被限制,則在系統(tǒng)空閑時或下一個周期開始時(以先到者為準),它將立即取消限制。
RT_RUNTIME_GREED
通過以下命令 啟用:
#echo RT_RUNTIME_GREED> /sys/kernel/debug/sched_features
要使所有CPU核都具有相同的rt_runtime
,請禁用NO_RT_RUNTIME_SHARE
邏輯:
#echo NO_RT_RUNTIME_SHARE> /sys/kernel/debug/sched_features
設置了這兩個選項后,用戶將保證所有CPU上的非RT任務都有一定的運行時間,同時使實時任務盡可能多地運行。
希望這個冷知識對大家有所幫助,對Linux感興趣的同學可以看一下教程:
Linux教程:http://o2fo.com/linux/
Linux微課:http://o2fo.com/minicourse/play/linuxcourse
Linux就該這么學:http://o2fo.com/linuxprobe/