<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      《Linux內核設計與實現》讀書筆記(四)- 進程的調度

      主要內容:

      • 什么是調度
      • 調度實現原理
      • Linux上調度實現的方法
      • 調度相關的系統調用

      1. 什么是調度

      現在的操作系統都是多任務的,為了能讓更多的任務能同時在系統上更好的運行,需要一個管理程序來管理計算機上同時運行的各個任務(也就是進程)。

      這個管理程序就是調度程序,它的功能說起來很簡單:

      1. 決定哪些進程運行,哪些進程等待
      2. 決定每個進程運行多長時間

      此外,為了獲得更好的用戶體驗,運行中的進程還可以立即被其他更緊急的進程打斷。

      總之,調度是一個平衡的過程。一方面,它要保證各個運行的進程能夠最大限度的使用CPU(即盡量少的切換進程,進程切換過多,CPU的時間會浪費在切換上);另一方面,保證各個進程能公平的使用CPU(即防止一個進程長時間獨占CPU的情況)。

       

      2. 調度實現原理

      前面說過,調度功能就是決定哪個進程運行以及進程運行多長時間。

      決定哪個進程運行以及運行多長時間都和進程的優先級有關。為了確定一個進程到底能持續運行多長時間,調度中還引入了時間片的概念。

      2.1 關于進程的優先級

      進程的優先級有2種度量方法,一種是nice值,一種是實時優先級。

      nice值的范圍是-20~+19,值越大優先級越低,也就是說nice值為-20的進程優先級最大。

      實時優先級的范圍是0~99,與nice值的定義相反,實時優先級是值越大優先級越高。

      實時進程都是一些對響應時間要求比較高的進程,因此系統中有實時優先級高的進程處于運行隊列的話,它們會搶占一般的進程的運行時間。

       

      進程的2種優先級會讓人不好理解,到底哪個優先級更優先?一個進程同時有2種優先級怎么辦?

      其實linux的內核早就有了解決辦法。

      對于第一個問題,到底哪個優先級更優先?

      答案是實時優先級高于nice值,在內核中,實時優先級的范圍是 0~MAX_RT_PRIO-1 MAX_RT_PRIO的定義參見 include/linux/sched.h

      1611 #define MAX_USER_RT_PRIO        100
      1612 #define MAX_RT_PRIO             MAX_USER_RT_PRIO

      nice值在內核中的范圍是 MAX_RT_PRIO~MAX_RT_PRIO+40 即 MAX_RT_PRIO~MAX_PRIO

      1614 #define MAX_PRIO                (MAX_RT_PRIO + 40)

       

      第二個問題,一個進程同時有2種優先級怎么辦?

      答案很簡單,就是一個進程不可能有2個優先級。一個進程有了實時優先級就沒有Nice值,有了Nice值就沒有實時優先級。

      我們可以通過以下命令查看進程的實時優先級和Nice值:(其中RTPRIO是實時優先級,NI是Nice值)

      $ ps -eo state,uid,pid,ppid,rtprio,ni,time,comm
      S   UID   PID  PPID RTPRIO  NI     TIME COMMAND
      S     0     1     0      -   0 00:00:00 systemd
      S     0     2     0      -   0 00:00:00 kthreadd
      S     0     3     2      -   0 00:00:00 ksoftirqd/0
      S     0     6     2     99   - 00:00:00 migration/0
      S     0     7     2     99   - 00:00:00 watchdog/0
      S     0     8     2     99   - 00:00:00 migration/1
      S     0    10     2      -   0 00:00:00 ksoftirqd/1
      S     0    12     2     99   - 00:00:00 watchdog/1
      S     0    13     2     99   - 00:00:00 migration/2
      S     0    15     2      -   0 00:00:00 ksoftirqd/2
      S     0    16     2     99   - 00:00:00 watchdog/2
      S     0    17     2     99   - 00:00:00 migration/3
      S     0    19     2      -   0 00:00:00 ksoftirqd/3
      S     0    20     2     99   - 00:00:00 watchdog/3
      S     0    21     2      - -20 00:00:00 cpuset
      S     0    22     2      - -20 00:00:00 khelper

       

      2.2 關于時間片

      有了優先級,可以決定誰先運行了。但是對于調度程序來說,并不是運行一次就結束了,還必須知道間隔多久進行下次調度。

      于是就有了時間片的概念。時間片是一個數值,表示一個進程被搶占前能持續運行的時間。

      也可以認為是進程在下次調度發生前運行的時間(除非進程主動放棄CPU,或者有實時進程來搶占CPU)。

      時間片的大小設置并不簡單,設大了,系統響應變慢(調度周期長);設小了,進程頻繁切換帶來的處理器消耗。默認的時間片一般是10ms

       

      2.3 調度實現原理(基于優先級和時間片)

      下面舉個直觀的例子來說明:

      假設系統中只有3個進程ProcessA(NI=+10),ProcessB(NI=0),ProcessC(NI=-10),NI表示進程的nice值,時間片=10ms

      1) 調度前,把進程優先級按一定的權重映射成時間片(這里假設優先級高一級相當于多5msCPU時間)。

          假設ProcessA分配了一個時間片10ms,那么ProcessB的優先級比ProcessA高10(nice值越小優先級越高),ProcessB應該分配10*5+10=60ms,以此類推,ProcessC分配20*5+10=110ms

      2) 開始調度時,優先調度分配CPU時間多的進程。由于ProcessA(10ms),ProcessB(60ms),ProcessC(110ms)。顯然先調度ProcessC

      3) 10ms(一個時間片)后,再次調度時,ProcessA(10ms),ProcessB(60ms),ProcessC(100ms)。ProcessC剛運行了10ms,所以變成100ms。此時仍然先調度ProcessC

      4) 再調度4次后(4個時間片),ProcessA(10ms),ProcessB(60ms),ProcessC(60ms)。此時ProcessB和ProcessC的CPU時間一樣,這時得看ProcessB和ProcessC誰在CPU運行隊列的前面,假設ProcessB在前面,則調度ProcessB

      5) 10ms(一個時間片)后,ProcessA(10ms),ProcessB(50ms),ProcessC(60ms)。再次調度ProcessC

      6) ProcessB和ProcessC交替運行,直至ProcessA(10ms),ProcessB(10ms),ProcessC(10ms)。

          這時得看ProcessA,ProcessB,ProcessC誰在CPU運行隊列的前面就先調度誰。這里假設調度ProcessA

      7) 10ms(一個時間片)后,ProcessA(時間片用完后退出),ProcessB(10ms),ProcessC(10ms)。

      8) 再過2個時間片,ProcessB和ProcessC也運行完退出。

      這個例子很簡單,主要是為了說明調度的原理,實際的調度算法雖然不會這么簡單,但是基本的實現原理也是類似的:

      1)確定每個進程能占用多少CPU時間(這里確定CPU時間的算法有很多,根據不同的需求會不一樣)

      2)占用CPU時間多的先運行

      3)運行完后,扣除運行進程的CPU時間,再回到 1)

       

      3. Linux上調度實現的方法

      Linux上的調度算法是不斷發展的,在2.6.23內核以后,采用了“完全公平調度算法”,簡稱CFS。

      CFS算法在分配每個進程的CPU時間時,不是分配給它們一個絕對的CPU時間,而是根據進程的優先級分配給它們一個占用CPU時間的百分比。

      比如ProcessA(NI=1),ProcessB(NI=3),ProcessC(NI=6),在CFS算法中,分別占用CPU的百分比為:ProcessA(10%),ProcessB(30%),ProcessC(60%)

      因為總共是100%,ProcessB的優先級是ProcessA的3倍,ProcessC的優先級是ProcessA的6倍。

       

      Linux上的CFS算法主要有以下步驟:(還是以ProcessA(10%),ProcessB(30%),ProcessC(60%)為例)

      1)計算每個進程的vruntime(注1),通過update_curr()函數更新進程的vruntime。

      2)選擇具有最小vruntime的進程投入運行。(注2)

      3)進程運行完后,更新進程的vruntime,轉入步驟2) (注3)

       

      注1. 這里的vruntime是進程虛擬運行的時間的總和。vruntime定義在:kernel/sched_fair.c 文件的 struct sched_entity 中。

       

      注2. 這里有點不好理解,根據vruntime來選擇要運行的進程,似乎和每個進程所占的CPU時間百分比沒有關系了。

      1)比如先運行ProcessC,(vr是vruntime的縮寫),則10ms后:ProcessA(vr=0),ProcessB(vr=0),ProcessC(vr=10)

      2)那么下次調度只能運行ProcessA或者ProcessB。(因為會選擇具有最小vruntime的進程)

      長時間來看的話,ProcessA、ProcessB、ProcessC是公平的交替運行的,和優先級沒有關系。

      而實際上vruntime并不是實際的運行時間,它是實際運行時間進行加權運算后的結果。

      比如上面3個進程中ProcessA(10%)只分配了CPU總的處理時間的10%,那么ProcessA運行10ms的話,它的vruntime會增加100ms。

      以此類推,ProcessB運行10ms的話,它的vruntime會增加(100/3)ms,ProcessC運行10ms的話,它的vruntime會增加(100/6)ms。

      實際的運行時,由于ProcessC的vruntime增加的最慢,所以它會獲得最多的CPU處理時間。

      上面的加權算法是我自己為了理解方便簡化的,Linux對vruntime的加權方法還得去看源碼^-^

       

      注3.Linux為了能快速的找到具有最小vruntime,將所有的進程的存儲在一個紅黑樹中。這樣樹的最左邊的葉子節點就是具有最小vruntime的進程,新的進程加入或有舊的進程退出時都會更新這棵樹。

       

      其實Linux上的調度器是以模塊方式提供的,每個調度器有不同的優先級,所以可以同時存在多種調度算法。

      每個進程可以選擇自己的調度器,Linux調度時,首先按調度器的優先級選擇一個調度器,再選擇這個調度器下的進程。

       

      4. 調度相關的系統調用

      調度相關的系統調用主要有2類:

      1) 與調度策略和進程優先級相關 (就是上面的提到的各種參數,優先級,時間片等等) - 下表中的前8個

      2) 與處理器相關 - 下表中的最后3個

      系統調用

      描述

      nice()

      設置進程的nice值

      sched_setscheduler()

      設置進程的調度策略,即設置進程采取何種調度算法

      sched_getscheduler()

      獲取進程的調度算法

      sched_setparam()

      設置進程的實時優先級

      sched_getparam()

      獲取進程的實時優先級

      sched_get_priority_max()

      獲取實時優先級的最大值,由于用戶權限的問題,非root用戶并不能設置實時優先級為99

      sched_get_priority_min()

      獲取實時優先級的最小值,理由與上面類似

      sched_rr_get_interval()

      獲取進程的時間片

      sched_setaffinity()

      設置進程的處理親和力,其實就是保存在task_struct中的cpu_allowed這個掩碼標志。該掩碼的每一位對應一個系統中可用的處理器,默認所有位都被設置,即該進程可以再系統中所有處理器上執行。

      用戶可以通過此函數設置不同的掩碼,使得進程只能在系統中某一個或某幾個處理器上運行。

      sched_getaffinity()

      獲取進程的處理親和力

      sched_yield()

      暫時讓出處理器

      posted @ 2017-08-24 17:22  閆寶平  閱讀(241)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国内自拍小视频在线看| 日本一区二区三区东京热| 麻豆一区二区中文字幕| 2020国产欧洲精品网站| 亚洲中文字幕精品久久| 亚洲国产一区二区三区最新| 国产免费高清69式视频在线观看| 亚洲高清免费在线观看| 欧洲精品色在线观看| 国产精品一二三区蜜臀av| 玩弄放荡人妻少妇系列| 日本无遮挡真人祼交视频| 99国产精品白浆在线观看免费| 韩国午夜福利片在线观看| 久久精品国产久精国产69| 钟山县| 91热在线精品国产一区| 欧美大胆老熟妇乱子伦视频| 99在线小视频| 无码人妻一区二区三区线| 91午夜福利一区二区三区| 中文字幕无码视频手机免费看| 美女无遮挡免费视频网站| 亚洲产在线精品亚洲第一站一| 亚洲欧美卡通另类丝袜美腿| 波多野结衣美乳人妻hd电影欧美 | 亚洲国产一区二区三区亚瑟| 人人爽人人模人人人爽人人爱| 拜城县| 欧美嫩交一区二区三区 | 家庭乱码伦区中文字幕在线| 东方四虎在线观看av| 极品尤物被啪到呻吟喷水| av一区二区中文字幕| 国产成人亚洲日韩欧美| 亚洲国产一区二区精品专| 日本一区二区三区专线| 欧美情侣性视频| 熟女女同亚洲女同中文字幕| 国产激情一区二区三区成人| 亚洲国产欧洲精品路线久久|