linux 程序排程2

2022-09-07 17:54:11 字數 2662 閱讀 5277

兩種情況:

執行太久, 需切換到另一程序;

高優先順序程序被喚醒

時鐘中斷處理函式會呼叫 scheduler_tick()檢視是否是需要搶占的時間點

void scheduler_tick(void

)

由時鐘中斷觸發檢測, 中斷處理呼叫 scheduler_tick

取當前程序 task_struct->task_tick_fair()->取 sched_entity cfs_rq 呼叫 entity_tick()

entity_tick() 呼叫 update_curr 更新當前程序 vruntime, 呼叫 check_preempt_tick 檢測是否需要被搶占

check_preempt_tick 中計算 ideal_runtime(乙個排程週期中應該執行的實際時間), 若程序本次排程執行時間 > ideal_runtime, 則應該被搶占

要被搶占, 則呼叫 resched_curr, 設定 tif_need_resched, 將其標記為應被搶占程序(因為要等待當前程序執行 `__schedule`)

當 i/o 完成, 程序被喚醒, 若優先順序高於當前程序則觸發搶占

try_to_wake_up()->ttwu_queue() 將喚醒任務加入佇列 呼叫 ttwu_do_activate 啟用任務

原始碼分析:

static

int try_to_wake_up(struct task_struct *p, unsigned int state, int

sync)

else

if (old_state &task_noninteractive)

p->sleep_type = sleep_noninteractive;//

同上activate_task(p, rq, cpu ==this_cpu);

if (!sync || cpu !=this_cpu)

success = 1;

out_running:

trace_sched_wakeup(rq, p, success);

p->state =task_running;

out:

task_rq_unlock(rq, &flags);

return

success;

}

1.    首先呼叫task_rq_lock( )禁止本地中斷,並獲得最後執行程序的cpu(他可能不同於本地cpu)所擁有的執行佇列rq的鎖。cpu的邏輯號儲存在p->thread_info->cpu欄位。

2.    檢查程序的狀態p->state是否屬於被當作引數傳遞給函式的狀態掩碼state,如果不是,就跳到第9步終止函式。

3.    如果p->array欄位不等於null,那麼程序已經屬於某個執行佇列,因此跳轉到第8步。

4.    在多處理器系統中,該函式檢查要被喚醒的程序是否應該從最近執行的cpu的執行佇列遷移到另外乙個cpu的執行佇列。實際上,函式就是根據一些啟發式規則選擇乙個目標執行佇列。

5.    如果程序處於task_uninterruptible狀態,函式遞減目標執行佇列的nr_uninterruptible欄位,並把程序描述符的p->activated欄位設定為-1。

呼叫activate_task( )函式:

static

void activate_task(struct task_struct *p, struct rq *rq, int

local)

}p->timestamp =now;

__activate_task(p, rq);}

static

void __activate_task(struct task_struct *p, struct rq *rq)

呼叫 tt_do_wakeup()->check_preempt_curr() 檢查是否應該搶占, 若需搶占則標記

標識當前執行中的程序應該被搶占了,但是真正的搶占動作並沒有發生

程序呼叫 `__schedule`,:分為使用者態和核心態

使用者態程序

時機-1: 從系統呼叫中返回, 返回過程中會呼叫 exit_to_usermode_loop, 檢查 `_tif_need_resched`, 若打了標記, 則呼叫 schedule(),呼叫的過程和上一節解析的一樣,會選擇乙個程序讓出 cpu,做上下文切換。

時機-2: 從中斷中返回, 中斷返回分為返回使用者態和核心態(彙編**: arch/x86/entry/entry_64.s), 返回使用者態過程中會呼叫 exit_to_usermode_loop()->shcedule()

核心態程序

時機-1: 發生在 preempt_enable() 中, 核心態程序有的操作不能被中斷, 會呼叫 preempt_disable(), 在開啟時(呼叫 preempt_enable) 時是乙個搶占時機, 會呼叫 preempt_count_dec_and_test(), 檢測 preempt_count 和標記, 若可搶占則最終呼叫 `__schedule`

時機-2: 發生在中斷返回, 也會呼叫 `__schedule`

參考:《趣談linux作業系統》排程(中)

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,核...

linux 程序排程

linux程序優先順序 1.nice值 20 19 預設0 nice值越大,程序優先順序越低 2.實時優先順序 0 99 實時優先順序越高,程序優先順序越高 任何實時程序的優先順序都高於普通的程序,也就是說實時優先順序和nice優先順序處於互補相交的兩個範疇 linux預設的程序排程模型是時間迴圈共...