進程的切換和系統的通常執行過程linux
1、進程切換的關鍵代碼switch_to分析git
1.進程調度與其時機分析github
分類:
第一種分類 I/O-bound:頻繁的進行I/O;會花不少時間等待I/O操做完成
CPU-bound:計算密集型;須要大量cpu時間進行計算
第二種分類 批處理進程:沒必要與用戶交互,一般在後臺進行;不行很快響應(編譯程序,科學計算)算法
實時進程:有實時需求,不被低優先級的進程阻塞;響應時間短,穩定(視頻/音頻,機械)
交互式進程:常常和用戶交互;花不少時間等待用戶輸入,響應時間快(shell;文本編輯器)
linux中的調度是多種調度策略和算法的混合:
是基於分時和優先級的;
進程的優先級是動態的;
*內核中的調度算法相關代碼使用了相似OOD中的策略模式
shell
進程調度的時機:
schedule函數:在運行隊列找到一個進程,把CPU分配給它(直接調用或者分散標記need_reched)
中斷處理過程當中,直接調用schedule(),或者返回用戶態schedule()根據標記來返回;
內核線程直接調用schedule()進行線程切換(內核線程是隻有內核態沒有用戶態的特殊進程);架構
用戶態沒法主動調度,僅能陷入內核態後的某個時機點進行調度(只能被動調度);編輯器
2.進程上下文切換相關代碼分析函數
進程的切換:線程
掛起正在CPU上執行的進程,與中斷時保存現場不一樣,中斷先後是同一個進程上下文中,由用戶態向內核態進行,包含了進程執行所須要的全部信息(用戶地址空間;控制信息;硬件上下文)調試
schedule()選擇一個新進程來運行,調用context_switch進行上下文切換,這個宏調用switch_to進行關鍵上下文切換
next=pick_next_task
context_switch(上下文切換)
switch_to(pre,next,last)
*next_ip通常是$1f,對於新建立的子進程是ret_from_fork
2、linux系統的通常執行過程
1.通常執行過程
正在運行X→發生中斷→SAVE_ALL(保存現場)→中斷處理過程或中斷返回前調用schedule(),其中的switch_to進行上下文切換→標號1後開始運行進程Y→RESTORE_ALL(恢復現場)→iret_pop→繼續運行用戶態Y
2.特殊狀況
內核線程發生中斷沒有進程用戶態,內核態轉換;
內核線程主動調用schedule(),只有進程上下文切換,沒有中斷文上下文切換;
建立子進程的系統調用在子進程的執行起點,以及返回用戶態(next_ip=ret_from_fork)
加載一個新的可執行程序後返回到用戶態的狀況(如exceve)
3.內核是各類中斷處理過程和內核進程的集合
3、linux系統架構和執行過程概覽
1.架構概覽
2.執行ls命令→肯定命令→fork生成一個shell自己的拷貝→exce將ls的可執行文件裝入內存→從系統調用返回
3.從CPU和內存的角度看linux的執行過程
4、實驗
1.
打開shell終端,執行如下命令:cd LinuxKernel
rm -rf menu
git clone https://github.com/mengning/menu.git
cd menu
mv test_exec.c test.c
make rootfs
2.
能夠經過增長-s -S啓動參數打開調試模式
qemu -kernel ../linux-3.18.6/arch/x86/boot/bzImage -initrd ../rootfs.img -s -S
打開gdb進行遠程調試
gdb
file ../linux-3.18.6/vmlinux
target remote:1234
設置斷點
b schedule
b context_switch
b switch_to
b pick_next_task
schedule()函數用來選擇一個新的進程來運行,並調用context_switch()進行上下文的切換,這個宏調用switch_to(switch_to利用了prev和next兩個參數:prev指向當前進程,next指向被調度的進程)來進行關鍵上下文切換,其中pick_next_task()函數封裝了進程調度算法。