【黎靜 原創做品轉載請註明出處 《Linux內核分析》MOOC課程http://mooc.study.163.com/course/USTC-1000029000】web
1.不一樣類型進程有不一樣調度需求——兩種分類算法
分類1shell
I/O-bound:等待I/O架構
CPU-bound:大量佔用CPU進行計算函數
分類2spa
交互式進程(shell)線程
實時進程rest
批處理進程blog
一組決定什麼時候以何種方式選擇進程的規則隊列
Linux的調度基於分時和優先級策略:
進程根據優先級(系統根據特定算法計算出來)排隊;
這個優先級的值表示如何適當分配CPU;
調度程序會根據進程的運行週期動態調整優先級;
好比nice等系統調用,能夠手動調整優先級
調度策略本質上是一種算法,這些算法從實現的角度看僅僅是從運行隊列中選擇一個新進程,選擇的過程當中運用了不一樣的策略而已
內核中的調度算法相關代碼使用了相似OOD中的策略模式
用戶地址空間:包括程序代碼,數據,用戶堆棧等
控制信息:進程描述符,內核堆棧等
硬件上下文(與中斷保存硬件上下文的方法不一樣)
X正在運行--->發生中斷,可能陷入內核,CPU自動保存加載--->SAVE_ALL保存現場--->調用schedule,switch_to進程上下文切換--->標號1以後運行Y(以前有進行準備動做)--->restore_all恢復現場--->iret- pop cs:eip/ss:esp/eflags from kernel stack--->繼續運行用戶態進程Y
經過中斷處理過程當中的調度時機,用戶態進程與內核線程之間互相切換和內核線程之間互相切換,與最通常的狀況很是相似,只是內核線程運行過程當中發生中斷沒有進程用戶態和內核態的轉換;
內核線程主動調用schedule(),只有進程上下文的切換,沒有發生中斷上下文的切換,與最通常的狀況略簡略;
建立子進程的系統調用在子進程中的執行起點及返回用戶態,如fork;
加載一個新的可執行程序後返回到用戶態的狀況,如execve;
過程:
shell分析-->調用系統調用fork生成一個shell自己拷貝-->調用exec系統調用將ls可執行文件裝入內存-->從系統調用返回
schedule()函數選擇一個新的進程來運行,並調用context_switch進行上下文的切換,context_switch是一個宏,這個宏調用switch_to()函數來進行關鍵上下文切換
next = pick_next_task(rq, prev); //進程調度算法都封裝這個函數內部
context_switch(rq, prev, next); //進程上下文切換
switch_to利用了prev和next兩個參數:prev指向當前進程,next指向被調度的進程