呂鬆鴻 + 原創做品轉載請註明出處 + 《Linux內核分析》MOOC課程http://mooc.study.163.com/course/USTC-1000029000算法
1、進程切換的關鍵代碼switch_to分析shell
1.進程調度與進程調度的時機分析架構
不一樣類型的進程有不一樣的調度需求函數
第一種分類:操作系統
- I/O-bound:頻繁進行I/O,花費很長時間等待I/O
- CPU-bound:計算密集型,須要大量CPU時間進行計算
第二種分類:線程
- 批處理進程:沒必要交互、很快響應
- 實時進程:要求響應時間短
- 交互式進程(shell)
調度策略:是一組規則,它們決定何時以怎樣的方式選擇一個新進程運行。3d
- Linux的進程根據優先級排隊
- Linux中進程的優先級是動態的
操做系統原理中介紹了大量進程調度算法,這些算法從實現的角度看僅僅是從運行隊列中選擇一個新進程,選擇的過程當中運用了不一樣的策略而已。rest
2.進程調度的時機blog
- 中斷處理過程(包括時鐘中斷、I/O中斷、系統調用和異常)中,直接調用schedule(),或者返回用戶態時根據need_resched標記調用schedule();
- 內核線程(只有內核態沒有用戶態的特殊進程)能夠直接調用schedule()進行進程切換,也能夠在中斷處理過程當中進行調度,也就是說內核線程做爲一類的特殊的進程能夠主動調度,也能夠被動調度;
- 用戶態進程沒法實現主動調度,只能被動調度,僅能經過陷入內核態後的某個時機點進行調度,即在中斷處理過程當中進行調度。
3.進程的切換隊列
- 爲了控制進程的執行,內核必須有能力掛起正在CPU上執行的進程,並恢復之前掛起的某個進程的執行,這叫作進程切換、任務切換、上下文切換;
- 掛起正在CPU上執行的進程,與中斷時保存現場是不一樣的,中斷先後是在同一個進程上下文中,只是由用戶態轉向內核態執行;
- 進程上下文包含了進程執行須要的全部信息
- 用戶地址空間:包括程序代碼,數據,用戶堆棧等
- 控制信息:進程描述符,內核堆棧等
- 硬件上下文(注意中斷也要保存硬件上下文只是保存的方法不一樣)
- schedule()函數選擇一個新的進程來運行,並調用context_switch進行上下文的切換,這個宏調用switch_to來進行關鍵上下文切換
- next = pick_ next_task(rq, prev);//進程調度算法都封裝這個函數內部
- context_switch(rq, prev, next);//進程上下文切換
- switch_to利用了prev和next兩個參數:prev指向當前進程,next指向被調度的進程
2、Linux系統的通常執行過程
- 最通常的狀況:正在運行的用戶態進程X切換到運行用戶態進程Y的過程
- 正在運行的用戶態進程X
- 發生中斷——save cs:eip/esp/eflags(current) to kernel stack,then load cs:eip(entry of a specific ISR) and ss:esp(point to kernel stack).
- SAVE_ALL //保存現場
- 中斷處理過程當中或中斷返回前調用了schedule(),其中的switch_to作了關鍵的進程上下文切換
- 標號1以後開始運行用戶態進程Y(這裏Y曾經經過以上步驟被切換出去過所以能夠從標號1繼續執行)
- restore_all //恢復現場
- iret - pop cs:eip/ss:esp/eflags from kernel stack
- 繼續運行用戶態進程Y
- 幾種特殊狀況
- 經過中斷處理過程當中的調度時機,用戶態進程與內核線程之間互相切換和內核線程之間互相切換,與最通常的狀況很是相似,只是內核線程運行過程當中發生中斷沒有進程用戶態和內核態的轉換;
- 內核線程主動調用schedule(),只有進程上下文的切換,沒有發生中斷上下文的切換,與最通常的狀況略簡略;
- 建立子進程的系統調用在子進程中的執行起點及返回用戶態,如fork;
- 加載一個新的可執行程序後返回到用戶態的狀況,如execve;
3、Linux系統架構和執行過程概覽
4、實驗
1.下載新的menu
2.設置斷點
3.單步追蹤