Linux內核分析-9/進程的調度時機


Linux內核分析-9/進程的調度時機

  • 上篇博客已經講了調度的路徑
  • 明白了
  • 1/調度都是在內核中間進行的,調用調度函數的函數A都是在內核態
  • 2/調用調度函數的函數A都是由兩個路徑
    • 1/用戶態陷入內核態,調用 調度 (時機根據內核版本不同而不同,但都是在內核態調用)
    • 2/因為中斷,進入中斷處理函數,調用 調度 (中斷處理函數在內核態中)

linux-0.11中的調度時機

  • linux-0.11中調用 schedule 函數的次數 屈指可數,總共8次
//次數 1 : do_timer(timer_interrupt->do_timer)
這個函數在時鍾中斷函數中被調用的, 函數 do_timer 直接調用了 schedule
//次數 2 : release
這個函數是 在exit 和wait uname 的 底層路徑 中調用的 ,函數 release 直接調用了 release
//次數 3 : do_exit
這個函數是 被 exit 和 signal do_no_page(頁異常中斷處理函數) 和其他系統調用 調用的 .
//次數 4 : sys_waitpid
這個函數是被 waitpid 調用的
//次數 5 : sys_pause
這個函數是被 pause 調用的
//次數 6 : sleep_on
這個函數 是被 sync dev open mount setup mkdir read umount execv 調用
//次數 7 : interruptible_sleep_on
這個函數是 不可中斷的睡眠,相對於 sleep_on(可中斷) 來說用的地方要少 ,被 open mount setup write read 調用
//次數 8 : tty_write
這個函數的調用路徑 tty_write(sys_write->rw_char->crw_table->rw_tty->rw_ttyx->tty_write- 寫阻塞 ->schedule)
  • 從上面可以看到,linux-0.11中的調用時機只有兩種:
    • 1.在系統調用路徑中
    • 2.在中斷處理函數路徑中

linux的調度時機

  • 可見linux-0.11中的調度時機分為兩種,一種是系統調用,一種是中斷處理函數,但歸結起來,都是中斷引起的.
  • 不過一個是軟中斷,一個是硬中斷
  • 但是后來的東西怎么變了呢?哪里變了呢?CHANGELOG
    • 分類變了,但還是哪兩種?現在被稱呼為主動調度 和被動調度
    • 1.主動調度就是之前的系統調用.
    • 2.被動調度還是之前的中斷處理和部分系統調用(都走 ret_from_sys_call ),不過這次不是在中斷處理過程中調用的 schedule 函數,而是在中斷處理函數返回之后,進入用戶態之前(即 ret_from_sys_call 之后)根據 進程調度標志 need_resched 調用的.
    • 3.另外linux-2.6之前的內核只支持從用戶態開始的的調度,不支持從內核態的調度.如果在內核態下,發生調度什么的,只能先出內核態(即到達用戶態),再陷入內核態做調度,這樣增加了消耗(內核態->用戶態->內核態 的 過程).內核態的搶占是通過 ( ret_from_sys_call ) 后的 preempt_schedule_irq 進行的
    • 要細分的話可以分為很多種,請看下面的分類
1/主動調度
1.1/正在執行的進程執行完畢。 例如 exit
1.2/正在執行的進程發出IO請求。例如 read
1.3/正在執行的進程要等待其他進程或系統發出的事情時。 wait
1.4/ 正在執行的進程中那是得不到所要的系統資源。 pthread_mutex_lock
2/被動調度(都是在ret_from_sys_call中被調用的,通過檢測 need_resched )
2.1/當中斷處理程序處理完中斷 IO中斷
2.2/進程釋放獨占資源 pthread_mutex_unlock
2.3/某進程發“發送消息”系統調用 signal
2.4/其他任何原因引起有進程從其他狀態變成就緒狀態 //進程被中調選中時
3/沒有新就緒進程,但原進程時間片到或優先級發生變化。
3.1/時鍾中斷函數中的 調用 調度
3.2/系統調用改變進程的優先級變化后的 調度
//什么時候需要調度?為什么?
//什么地方會調度?代碼中
Linux的進程調度時機與現代操作系統中的調度時機基本一致,為了判斷是否可以執行內核的進程調度程序來調度進程,Linux中設置了進程調度標志 need_resched ,當標志為1時,可執行調度程序.
通常,Linux調度時機分以下兩種情況:
(1)主動調度:指顯式調用schedule()函數明確釋放CPU,引起新一輪調度.一般發生在當前進程狀態改變,如:進程終止、進程睡眠、進程對某些信號處理過程中等.
(2)被動調度:指不顯示調用schedule()函數,只是PCB中的 need_resched 進程調度標志,該域置位為1將引起新的進程調度,而每當中斷處理和系統調用返回時,核心調度程序都會主動查詢need_resched的狀態(若置位,則主動調用 schedule ()函數。一般發生在新的進程產生時、某個進程優先級改變時、某個進程等待的資源可用被喚醒時、當前進程時間片用完等.
  1、進程狀態轉換的時刻:進程終止、進程睡眠;
  2、當前進程的時間片用完時(current->counter=0);
  3、設備驅動程序
  4、進程從中斷、異常及系統調用返回到用戶態時;
void resched_task(struct task_struct *p)
{
int cpu;

assert_raw_spin_locked(&task_rq(p)->lock);

if (test_tsk_need_resched(p))
return;

set_tsk_need_resched(p);

cpu = task_cpu(p);
if (cpu == smp_processor_id())
return;

/* NEED_RESCHED must be visible before we test polling */
smp_mb();
if (!tsk_is_polling(p))
smp_send_reschedule(cpu);
}

img

img


資料

linux調度器源碼分析 - 概述(一)

need_resched 是怎么使用的(ZT)

調度時機分析之被動調度(之內核態搶占調度)

進程調度的時機與進程的切換

深入分析linux調度機制
Linux進程調度機制


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2020 ITdaan.com