第八週讀書筆記

第四章 進程調度

1、多任務

1.非搶佔式多任務

進程會一直執行直到本身主動中止運行(這一步驟稱爲讓步)linux

2.搶佔式多任務

Linux/Unix使用的是搶佔式的方式;強制的掛起進程的動做就叫作搶佔。進程在被搶佔以前可以運行的時間是預先設置好的(也就是進程的時間片)算法

2、策略

1. I/O消耗型和處理器消耗型的進程

(1)進程分爲I/O消耗型和處理器消耗型函數

  • I/O消耗型:進程的大部分時間用來提交I/O請求或是等待I/O請求。這樣的進程常常處於可運行狀態,但一般是短短一下子。由於它在等待更多的I/O請求時最後總會阻塞。ui

  • 處理器消耗型:把時間大多用在執行代碼上。除非被搶佔,不然一直不停地運行。對於這類,調度策略儘可能下降他們的調度頻率,而延長其運行時間。spa

(2)調度策略一般在兩個矛盾的目標中間尋找平衡:進程響應迅速(響應時間短)和最大系統利用率(高吞吐量)。unix

(3)Unix系統更傾向於I/O消耗型程序,以提供更好的程序響應速度。隊列

2. 進程優先級

在某些系統中,優先級高的進程使用的時間片也比較長。調度程序老是選擇時間片未用盡並且優先級最高的進程運行。用戶和系統均可以經過設置進程的優先級來影響系統的調度。進程

Linux採用了兩種不一樣的優先級範圍——nice值和實時優先級值。事件

(1) nice值,範圍是-20到19,數值越大優先級越低,默認值爲0。Linux中,nice值則表明時間片的比例。能夠經過ps-el命令查看系統中的進程列表,結果中標記NI的一列就是進程對應的nice值。內存

(2) 實時優先級值,默認0到99,數值越大優先級越高。任何實時進程的優先級都高於普通的進程。
查看進程列表以及對應的實時優先級:ps-eo state,uid,pid,ppid,rtprio,time,comm.

3.時間片

代表進程被搶佔前所能持續運行的時間。長時間片致使系統交互表現欠佳。

(1)Linux的CFS調度器:沒有直接分配時間片到進程,而是將處理器的使用比劃分給進程。其搶佔時機取決於新的可運行程序消耗了多少處理器使用比。若是消耗的使用比比當前進程小,馬上投入運行,搶佔當前進程;不然推遲運行。

3、Linux調度算法

1.調度器類

(1)Linux調度器是以模塊方式提供的(也就是調度器類),目的是容許不一樣類型的進程能夠有針對性地選擇調度算法

(2)調度器類容許多種不一樣的可動態添加的調度算法並存,調度屬於本身範疇的進程;

(3)調度器代碼會按照優先級順序遍歷調度類,擁有一個可執行進程的最高優先級的調度器類勝出,去選擇下面要執行的那一個程序;

2.Unix中系統調度問題

(1)將nice值映射到時間片的話,就必須將nice值對應處處理器的絕對時間;這樣會致使進程切換沒法最優進行;

(2)若是使用相對nice值,所帶來的效果將會極大取決於其nice的初始值;

(3)若是執行nice值到時間片的映射,時間片極大受制於定時器。

3.公平調度

  • 目標延遲:CFS爲完美多任務中的無限小調度週期的近似值設立的一個目標。越小的調度週期將帶來越好的交互性,同時也更接近完美的多任務。但必須承受更高的切換代價和更差的系統總吞吐能力。

  • 最小粒度:CFS引人每一個進程得到的時間片底線,這個底線稱爲最小粒度。

CFS中,任何進程所得到的處理器時間是由它本身和其餘全部可運行進程nice值的相對差值決定。任何nice值對應的絕對時間是處理器的使用比。

4、Linux調度的實現

1.時間記帳

  • 全部的調度器都必須對進程的運行時間作記帳;
  • CFS使用調度器實體結構來追蹤運行記帳

2.虛擬實時

  • vrntime變量【也就是在上面所說的實體結構中】存放虛擬運行時間。虛擬時間以ns爲單位,和節拍定時器無關;
  • update_curr()函數實現了記帳功能;計算了當前進程的執行時間並將其存放在data_exec中;而後將運行時間傳遞給了_update_curr(),由後者再根據當前可運行進程總數對運行時間進行計算,最終肯定上述的權重值與當前運行進程的vrntime。

3.進程選擇

(1)CFS算法核心:選擇具備最小vrntime的任務

(2)具體作法:利用紅黑樹rbtree(以節點形式存儲數據的二叉樹)

4.進程調度入口

(1)進程調度的主要入口點是函數schedule(),定義在kernel/sched.c中;這正是內和其餘部分用於調度進程調度器的入口

(2)這一函數最重要的工做就是調用pick_next_state(),依次檢查每個調度類,並從最高優先級的調度類中,選擇最高優先級進程

5.睡眠和喚醒

(1)進程休眠必定是爲了等待一些事件

  • 進程把本身標記成休眠狀態,從可執行紅黑樹中移除;
  • 放入等待隊列——由等待某些時間發生的進程組成的鏈表,內核用wake_queue_head_t來表明等待隊列

(2)喚醒操做由函數wake_up()進行

  • 它會調用函數try_to _wake_up()將進程設置爲TASK_RUNNING狀態,調用enqueue_task()將進程放入紅黑樹中
  • 固然,也存在虛假喚醒進程的狀態

5、搶佔和上下文切換

上下文切換由定義在kernel/sched.c中的context_switch()函數負責,每當一個新的進程被選出來準備運行的時候,schedule()就會調用該函數:

  • switch_mm(),負責把虛擬內存從上一個進程映射切換到新的進程中;
  • switch_to(),負責從上一個進程的處理器狀態切換到新進程的處理器狀態

1.用戶搶佔

發生時機:

  • 從系統調用返回用戶空間時;
  • 從中斷處理程序返回用戶空間時。

2.Linux系統支持內核搶佔

(1)只要沒有鎖,內核就能夠進程搶佔;

(2)爲了支持搶佔,每一個進程的thread_info都加入了preempt_count計數器(初值爲0,每當使用鎖的時候就加1,釋放鎖的時候數值減1),當數值爲0時,內核就能夠搶佔

(3)內核搶佔發生在:

  1. 中斷處理程序正在執行且返回內核空間以前;
  2. 內核代碼再一次具備可搶佔性的時候;
  3. 內核中的任務顯式地調用schedule函數

6、實時調度策略

  • linux 提供兩種實時調度策略SCHED_FIFO和SCHED_RR。

  • SCHED_FIFO實現了一種簡單的、先入先出的調度算法:它不使用時間片.處於可運行狀態的SCHED_FIFO 級的進程會比任何SCHED_NORMAL 級的進程都先獲得調度。
  • SCHED_RR級的進程在耗盡事先分配給它的時間後就不能再繼續執行了.即 SC阻止RR 是帶有時鬧片的SCHED_FIFO-這是一種實時輪流調度算掛。
相關文章
相關標籤/搜索