核心中有乙個結構叫執行列隊(runqueue),根據實時和完全公平排程器類的需求,裡面嵌入了cfs_rq和rt_rq兩個列隊:
struct rq
struct task_struct
可以猜測核心通過在task_struct中嵌入sched_[***_]entity,以這些entity為"錨點"將程序在rq中的[***]_rq組織起來。
先看實時程序的組織方式:
struct rt_rq
struct rt_prio_array ;
struct sched_rt_entity
很明顯,sched_rt_entity根據程序的實時優先順序通過run_list掛到rt_rq.active.[實時優先順序]這條雙鏈表中。
再看下普通程序:
struct cfs_rq
struct sched_entity
很明顯,由於普通程序數量比較多,使用紅黑樹來管理,查詢效率會高很多。普通程序中的sched_entity是通過run_node掛到以cfs_rq.tasks_timeline為根節點的紅黑樹中。
sched.h中在每個cpu中都建立了乙個名為runqueues的rq結構:
declare_per_cpu_shared_aligned(struct rq, runqueues);
總結成一張圖說明核心如何將程序以排程實體組織起來:
什麼時候排程?也就是何時該去發動排程器去切換下乙個任務?
假設所有程序都非常自覺,當自己在等資源時會主動去睡眠,或者當自己執行一段時間時會主動放棄cpu讓其他程序執行,那麼世界就是美好的,大家都相互禮讓一片和諧。但是事實是殘酷的,這種情況一般都存在於一些封閉系統(封閉系統的軟體一般都是精心設計過的)。
在linux這樣的開放式核心有兩個核心排程器:scheduler_tick和schedule,當乙個程序覺得自己無事可做時,可以自覺地呼叫schedule放棄cpu。當然,對於不夠自覺想霸佔cpu的程序,核心會週期性的呼叫scheduler_tick檢查當前程序是不是占用cpu太久,進而使它放棄cpu。
/*
* all the scheduling class methods:
*/const struct sched_class fair_sched_class = ;
在面對物件程式設計中有乙個重要的特性叫多型,多型即在繼承父類之後,子類可以直接繼承或者擴充套件自己的方法和屬性,排程器類的設計就有這種思路在裡面:
假設一種排程思路,先設計乙個主排程器,再設計若干個排程器類(不一定一次性設計出多個可以後續根據需求新增)。主排程器的主要工作負責在確定排程時機,當需要切換下乙個任務時根據一定的順序在各個排程器類中選出乙個新的任務進行排程即可,如下面偽**:
class 主排程器:
@classmethod
def 註冊乙個排程器類(排程器類):
...def 排程:
for 排程器類 in 所有排程器類:
if (新程序 = 排程器類.選取乙個新程序()) != null
break
self.切換到新程序(新程序)
def main:
主排程器.註冊乙個排程器類(新排程器類)
主排程器.註冊乙個排程器類(新排程器類)
主排程器.註冊乙個排程器類(新排程器類)
while(true):
...if 排程時機成熟:
主排程器.排程()
...
... Linux任務排程
任務排程 是指系統在某個時間執行的特定的命令或程度。任務排程分類 i.系統工作 有些重要的工作必須周而復始地執行。如病毒掃瞄等。ii.個別使用者工作 個別使用者可能希望執行某些程式。設定任務排程檔案 etc crontab 設定個人任務排程 crontab e 希望,每分去執行可以在crontab ...
linux程序排程
排程 從就緒的程序選出最適合的乙個來執行。知識點 1 排程策略 2 排程時機 3 排程步驟 排程策略 sched normal sched other 普通的分時程序 sched fifo 先入先出的實時程序 sched rr 時間片輪轉的實時程序 sched batch 批處理程序 sched i...
linux程序排程
搶占就是程序排程,使用者程序搶占發生在以下情況 1 從系統呼叫返回使用者空間的時候 2 從中斷處理程式返回使用者空間時。在時鐘中斷中會呼叫scheduler tick 函式,該函式在程序時間片用完的時候會設定need resched標誌,當從時鐘中斷或者其他中斷返回後檢查need resched,核...