Linux核心 程序排程

2021-06-26 16:30:51 字數 3122 閱讀 3401

#搶占式多工:由排程程式來決定什麼時間停止乙個程序的執行

#程序的時間片:分配給每個可執行程序的處理器時間段

#o(1)排程程式

#反轉樓梯最後期限排程演算法(rsdl)

#完全公平排程演算法(cfs)

#i/o消耗型和處理器消耗型程序:

i/o消耗型程序:大部分時間用來提交i/o請求或等待i/o請求

處理器消耗型程序:把時間大部分用在執行**上。

排程策略往往降低他們的排程頻率,延長執行時間

#排程策略往往要在兩個矛盾中尋找平衡:

程序響應迅速(響應時間短)和最大系統利用率(高吞吐量)

# 程序優先順序

基於優先順序的排程:根據程序的價值和對處理器時間的需求來對程序分級的想法

排程程式總是選擇時間片未用盡而且優先順序高的程序先進行

#時間片:它表明程序在被搶占前所能持續執行的時間

*任何長時間片都將導致系統互動表現欠佳

#排程器類:linux排程器以模組形式提供,允許不同型別的程序選擇不同的排程演算法

#公平排程(cfs):cfs的做法是允許每個程序執行一段時間、迴圈輪轉、選擇執行最少的程序作為下乙個執行程序

*cfs在所有可執行程序總數基礎上計算出乙個程序應該執行多久,而不是依靠nice值來計算時間片

#最小粒度:每個程序獲得的時間片底線

1.時間記賬:

#排程器實體結構:cfs沒有時間片的概念,但是它必須維護每個程序執行的時間記賬,為了每個程序只在公平分配的處理器時間內執行

*排程器實體結構嵌入在程序描述符內

2.虛擬實時:

*vruntime變數存放程序的虛擬執行時間,該時間的計算是經過了所有可執行程序總數的標準化

*csf使用vruntime來記錄乙個程式執行了多長時間和它還應該執行多久

1.挑選下乙個任務:由函式_pick_next_entity()實現:

*執行rbtree樹中最左邊葉子節點代表的那個程序

*函式的返回值cfs排程選擇的下乙個執行程序,如果返回null,表示沒有可執行程序,cfs排程器選擇idle任務執行

2.向樹中加入程序:發生在程序變為可執行狀態或者通過fork()呼叫第一次建立程序時

*由enqueue_entity()實現,更新執行時間和一些統計資料,然後進行插入操作,把資料插入紅黑樹中

最後rb_insert_color()更新樹的自平衡相關屬性

3.從樹中刪除程序:發生在程序阻塞或者終止時

*由輔助函式_dequeue_entity()完成

*呼叫pick_next_task(),會以優先順序為序,從高到低,依次檢查每乙個排程類,並且從最高優先順序的排程類中,選擇最高優先順序的程序

睡眠:程序把自己標記為休眠狀態,從可執行紅黑樹中移出,放入等待佇列,然後呼叫schedule()選擇和執行乙個其他程序

喚醒:程序被設定為可執行狀態,從等待佇列移回可執行紅黑樹

1.等待佇列:等待某些時間發生的程序組成的簡單鍊錶

*休眠通過等待佇列進行處理

*核心用wake_queue_head_t來表示等待佇列,可以通過declare_waitqueue()靜態建立或init_waitqueue_head()動態建立

過程:1.呼叫巨集define_wait()建立乙個等待佇列的項

2.呼叫add_wait_queue()把自己加入到佇列中

3.呼叫prepare_to_wait()方法將程序的狀態變更為task_interruptible或者task_uninterruptible

4.如果狀態被設定為task_interruptible則訊號喚醒程序(偽喚醒)

5.當程序被喚醒時,它會檢查條件是否為真,如果是,則退出迴圈,再次呼叫呼叫schedule()並重複

6.當條件滿足後,程序將自己設定為task_running,並呼叫finish_wait()移出等待佇列

2.喚醒:通過wake_up()函式,它會喚醒指定等待佇列上的所有程序,它呼叫try_to_wake_up(),該函式將程序設定為task_running,呼叫enqueue_task()將此程序放入紅黑樹中。

*如果被喚醒的程序優先順序比當前正在執行的程序優先順序高,需要設定need_resched標誌

上下文切換就是從乙個可執行程序切換到另乙個可執行程序,由context_switch()負責處理

*它完成了兩項基本工作:

1.呼叫swtich_mm(),把虛擬記憶體從上乙個程序對映到新程序

2.呼叫swtich_to(),從上乙個程序的處理器狀態切換到新程序的處理器狀態(儲存、恢復棧資訊和暫存器資訊等)

#使用者搶占:在以下情況時發生:

1.從系統呼叫返回使用者空間時

2.從終端處理程式返回使用者空間時

#核心搶占:

如何實現:為每個程序的thread_info引入preempt_count計數器。初始值為0,使用鎖的時候+1,釋放鎖的時候-1,當為0時可執行搶占

從中斷返回核心空間時,核心會檢查need_resched和preempt_count,如果need_resched被設定,preempt_count為0,說明有乙個更重要的任務需要執行並可以搶占,此時,排程程式就會被呼叫

核心搶占發生在:

#中斷處理程式正在執行,且返回核心空間之前

#核心**再一次具有可搶占性的時候

#如果核心中的任務顯式地呼叫schedule()

#如果核心中的任務阻塞(同樣會呼叫schedule())

實時排程策略:sched_fifo和sched_rr

非實時排程策略:sched_normal

#sched_fifo:先入先出排程演算法,不使用時間片,sched_fifo級程序會比sched_normal級先得到排程

#sched_rr:與sched_fifo大體相同,是帶有時間片的sched_fifo,是一種實時輪流排程演算法

linux提供了乙個系統呼叫族,用於管理與程序排程相關的引數

#與排程策略和優先順序相關的系統呼叫:

sched_setscheduler():設定程序的排程策略和實時優先順序

sched_getschedular():獲取程序的排程策略和實時優先順序

sched_setparam():設定程序的實時優先順序

sched_getparam():獲取程序的實時優先順序

#與處理器繫結有關的系統呼叫

linux排程程式提供強制的處理器繫結機制

linux核心 5 核心程序排程與程序切換

一 程序排程 程序被建立到了鍊錶中,如何再進行進一步的呼叫和排程?程序排程 void schedule void 程序排程函式 switch to next 程序切換函式 一 void schedule void 程序排程函式 1 看一下 呼叫了schedule函式,在system call中尋找也...

linux核心程序排程系列之排程概述

多工作業系統分為非搶占式多工和搶占式多工。linux採用的是搶占式多工的模式,這就意味著程序對cpu的占用時間是由作業系統決定的,跟具體的說,由作業系統的程序排程程式所決定的,這個章節就介紹關於程序的排程策略。一 排程策略 1 其實程序的排程策略和程序的型別有關 第一種分配方法 cpu消耗型和i o...

linux核心之程序排程(一)

等待佇列 sleep相關函式將程序的狀態設定為非執行態,在下一次排程來時,將在schedule函式中將本程序從執行佇列中移除。sleep函式將程序加入等待佇列,然後呼叫schedule函式選擇並重新開始另乙個程式的執行。當呼叫wake up類函式將程序喚醒時,wake up類函式將程序加入執行佇列中...