pkzd之進程設計策略之進程調度

   本文主要討論單處理器上的進程調度算法,在討論具體的算法以前先假設存在一個具體的操做系統好比pkzd。linux

  假設該系統pkzd並不存在搶佔進程調度,而後咱們考慮接下來的狀況:算法

  •          假設在內存中同時存在進程p1, p2, p3(此處爲了方便不討論進程換出的狀況), p1, p2, p3的運行時間分別爲10ms, 100ms, 1000ms, 若是系統依次運行進程,那麼平均的等待時間約爲40ms, 若是進程達到的順序爲p3, p2, p1,那麼平均的等待時間約爲370ms。進程的平均等待時間由於進程達到的順序而存在巨大的差距,更有甚者,若是存在一個進程的運行時間爲無窮,那麼它將佔用全部的cpu時間,這明顯是不合理的,因此必須引入一種機制來保證公平調度。注: 非搶佔式系統存在不少的調度算法,有的算法能縮小由於進程達到順序不一樣而形成的平均等待時間之間的差距,可是有的算法實現並不是很簡單,好比SJF算法。另外全部的非搶佔式系統都沒法很好的處理永遠不會終止的進程(好比系統中存在不少的死循環)。shell

  單處理器中進程調度所要達到的目標就是讓全部的進程公平的分配cpu時間,咱們先來討論其中一種比較古老又簡單質樸的辦法:性能

  •     RR算法,該算法主要的想法是給全部的進程分配一個時間片,一個進程至多佔用一個時間片,一旦時間片用完就必須調用其餘的進程。能夠用鏈表實現該算法(固然這不是最好的實現辦法, 也不必定是最簡單的,之因此用鏈表只是由於本人以爲用鏈表比較簡單,不過你不必定這麼認爲):spa

    • head---p1----p2---p3------pn操作系統

    head指向進程鏈表的頭部,p1, p2至pn表明進程。假設操做系統給每一個進程分配一個固定的時間片10ms(注:該值的大小在用RR算法的系統中對整個操做系統的性能會有很大的影響,該值大小的設定必需要慎重,最後10ms是一個不錯的能夠考慮的時間片大小的值),而後內核首先調用進程p1,在運行一段時間後(小於等於10ms, 若是進程p1阻塞於某個事件,那麼運行事件將小於10ms, 一種極端狀況可能爲幾ns),內核將p1添加到進程鏈表的尾部,而且從新設置進程p1的時間片爲10ms,而後內核繼續調用進程p2,就這樣內核不停的調用不一樣的進程來保證公平。線程

    RR算法簡單有效的實現了一種公平的調度機制,不過該算法存在一些問題,好比如下狀況:進程

    •     存在進程p一、 p2, 假設p1進程是一個正在運行的shell, p2則是一個暴力破解的程序(可能會運行幾天)。首先內核調用進程p1,由於用戶沒有在鍵盤輸入任何數據因此p1運行1ns就陷入睡眠,而後內核調用p2運行,在運行一段時間後(由於p1在睡眠中,因此運行的程序一直是p2),用戶輸入一些字符(多是一個命令ls),而後內核喚醒進程p1,等待p2的時間片結束,以後調用p1,p1執行命令ls後繼續陷入睡眠(此次執行的時間假設爲1ms)。內核就這樣周而復始的不斷調用p1和p2, 可能你已經發現,在這種狀況下p2佔用的cpu時間會遠遠大於p1,這明顯是不公平的。另外對於交互式系統,用戶老是但願在按下鍵的時候獲得響應,用戶一般不會關心後臺進程是否正在運行,因此通常認爲交互式進程應該獲得更高的優先級以能被儘快調度。事件

  一種改進的機制是加入優先級,實現方式多是按優先級將全部的進程分類,好比等待鍵盤輸入的進程放到類I/O字符中,等待內存的放到類mem中,等待磁盤的放到類I/O塊中,內核每次調度都先從I/0字符類(該類的進程通常都和叫魂有關,因此有更高的優先級)開始查找能運行的進程,若是找不到就去下一個類中尋找,最後若是全部的類都不存在可運行的進程,內核就從idle類中找出一個空轉進程並運行它。將全部的進程分類的辦法可讓I/0密集進程等到更公平的對待,而且因爲I/O密集進程的大部分時間都在睡眠,因此cpu密集的進程也能獲得較好的對待。不過這樣的實現一樣存在問題:內存

    考慮如下狀況,操做系統存在10萬個進程,5萬個I/O密集進程, 5萬個CPU密集進程,那麼可能發生一種狀況,內核將老是從I/O類中調度進程而不會轉入cpu類中,如此將會有5萬個進程被不公平的對面,而且可能永遠都不會被運行。對於這種狀況,一種可能的改進方法是增長一些計數變量來觀測全部的進程類,在內核將要調度進程時內核根據計數變量來選擇合適的類(好比類中的進程所佔用的總的cpu數目,進程數,調度次數等),固然這將是一個複雜的實現。

 接下來講明一下linux的調度機制,linux與通常的時間片調度算法不一樣,它所採用的是一種比例的方法來對全部的進程分配時間片,linux的算法很好的保證了全部進程的一個調度(雖然在進程數目暴增時,它的保證將再也不有效)。

  至於線程調度,這是一個更加複雜的話題,一個簡答的例子,對於不一樣進程的線程是否要同等對待就是一個值得考慮的問題,由於本文字數有限就不討論了。

 最後,調度算法對整個操做系統的性能會產生很大的影響,而且對於不一樣的進程,內核如何差異對待而且保證公平也是個值得考慮的問題,好比PC上的交互式進程通常狀況應該比cpu密集的進程得到更多的調度機會,而一些特殊的狀況,好比一個核武器的演算進程應該比一個交互進程得到更多的cpu纔對。無論如何調度機制要保證的是全部的進程被公平的對待,對於I/O密集的進程應該保證其運行時間而給予更多的調度次數,而cpu密集的進程應該適當的減小其調度次數來減小其佔用cpu的時間。

相關文章
相關標籤/搜索