兩種情況:
執行太久, 需切換到另一程序;
高優先順序程序被喚醒
時鐘中斷處理函式會呼叫 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 啟用任務
原始碼分析:
static1. 首先呼叫task_rq_lock( )禁止本地中斷,並獲得最後執行程序的cpu(他可能不同於本地cpu)所擁有的執行佇列rq的鎖。cpu的邏輯號儲存在p->thread_info->cpu欄位。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;
}
2. 檢查程序的狀態p->state是否屬於被當作引數傳遞給函式的狀態掩碼state,如果不是,就跳到第9步終止函式。
3. 如果p->array欄位不等於null,那麼程序已經屬於某個執行佇列,因此跳轉到第8步。
4. 在多處理器系統中,該函式檢查要被喚醒的程序是否應該從最近執行的cpu的執行佇列遷移到另外乙個cpu的執行佇列。實際上,函式就是根據一些啟發式規則選擇乙個目標執行佇列。
5. 如果程序處於task_uninterruptible狀態,函式遞減目標執行佇列的nr_uninterruptible欄位,並把程序描述符的p->activated欄位設定為-1。
呼叫activate_task( )函式:
static呼叫 tt_do_wakeup()->check_preempt_curr() 檢查是否應該搶占, 若需搶占則標記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)
標識當前執行中的程序應該被搶占了,但是真正的搶占動作並沒有發生
程序呼叫 `__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預設的程序排程模型是時間迴圈共...