進程調度時機與進程切換分析

張建幫 原創作品轉載請註明出處 《Linux內核分析》MOOC課程http://mooc.study.163.com/course/USTC-1000029000

1 實驗目的

理解進程調度時機跟蹤分析進程調度與進程切換的過程

2 實驗過程

  1. 使用gdb跟蹤分析一個schedule()函數 ,使用網站 實驗樓 進行試驗

  2. 打開shell,進入 /home/shiyanlou/LinuxKernel/menu 目錄

  3. 由於實驗樓的虛擬機不能聯網,也就不能使用 git clone 命令進行復制,於是打開孟寧老師的 github主頁 ,將其中的 test_exec.c 的內容覆蓋 menu 目錄下的 test.c,將 Makefile 的內容覆蓋 menu 目錄下的 Makefile,同時新建 hello.c 文件,將其內容也複製過來

  4. 使用 make rootfs 命令查看當前系統,如下所示:
    這裏寫圖片描述
    可以看到和上次實驗的版本相同

  5. 添加 -s -S 選項進行調試,在menu目錄下,輸入下面命令:
    qemu -kernel ../linux-3.18.6/arch/x86/boot/bzImage -initrd ../rootfs.img -s -S

  6. 新建一個 shell 窗口進行 gdb 調試。在 gdb 調試窗口中先輸入 b sys_execve,準備對 exec 命令進程調試,然後輸入 c 以便讓程序繼續運行,最後在出現的界面中輸入 exec 命令,gdb窗口也暫停在 sys_execve 處

  7. 在 gdb 窗口中輸入下面命令:

b schedule
b context_switch
b pick_next_task 

輸入 b switch_to 命令時,提示 switch_to 函數未定義,因爲 switch_to 僅僅只是一個宏而已,因此出現上述提示。
8. 接下來 輸入 c 繼續執行,gdb 在斷點 __schedule 函數處停了下來,接下來連續輸入 c 都是在此處停了下來,說明我們的程序還沒有得到調度。
9. 在輸入不知道多少次 c 後,我終於決定放棄等到它得到調度的那一刻,直接調用 delete 刪除所有斷點後,再輸入 c ,終於看到了結果:

這裏寫圖片描述

這也進一步說明了在cpu的內部,調度是頻繁發生着的

3 實驗總結:

通過實驗可知schedule()函數用來選擇一個新的進程來運行,並調用context_switch宏進行上下文的切換,這個宏調 用switch_to來進行關鍵上下文切換,其中pick_next_task()函數封裝了進程調度算法。

而進程調度時機有三種情況:

1、中斷處理過程(包括時鐘中斷、I/O中斷、系統調用和異常)中,直接調用schedule(),或者返回用戶態時根據need_resched標記調用schedule();

2、內核線程可以直接調用schedule()進行進程切換,也可以在中斷處理過程中進行調度,也就是說內核線程作爲一類的特殊的進程可以主動調度,也可以被動調度,若是主動調度,則沒有中斷上下文的切換;

3、用戶態進程無法實現主動調度,僅能通過陷入內核態後的某個時機點進行調度,即在中斷處理過程中進行調度。

掛起正在CPU上執行的進程,與中斷時保存現場是不同的,中斷前後是在同一個進程上下文中,只是由用戶態轉向內核態執行。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章