1. 程式人生 > 其它 >linux 的排程策略與優先順序

linux 的排程策略與優先順序

技術標籤:初學linuxlinux排程策略與優先順序程序/執行緒排程機制

linux 的排程策略與優先順序

參考資料如下:

  1. man手冊man 7 sched
  2. 核心文件 Documentation/scheduler。

首先需要說明,我們常說的程序排程器是傳統的說法,但是實際上程序是資源管理的單位,執行緒才是排程的單位.有時也會說任務排程等。

linux的排程機制由排程策略(policies)優先順序(priority)兩個屬性共同決定.其中排程策略又可以分為實時排程策略通用排程策略(非實時)。其中通用排程策略的優先順序值為0.而實時排程策略的優先順序取值範圍為1~99.可以看出,實時排程策略的優先順序總是大於通用排程策略。而優先順序

高執行緒的總是會被排程器優先呼叫。其中實時排程策略包含SCHED_RR,SCHED_FIFO排程策略。通用排程策略包含SCHED_OTHERSCHED_IDLESCHED_BATCH排程策略。即如下關係:
linux的排程機制由排程策略(policies)優先順序(priority)共同決定:

  1. 優先順序:確定哪個執行緒被優先排程。實時排程策略的優先順序總是大於通用排程策略。
  2. 排程策略(policies)分如下幾種:
    1. 實時排程策略:spriority值的取值範圍為0~99.當執行緒間的優先順序不同時,按照優先順序高的先排程原則。當優先順序相同時,分為如下兩種方式:
      1. SCHED_RR:優先順序相同的執行緒按固定的時間片
        迴圈排程。下面會詳細講解。
      2. SCHED_FIFO:與SCHED_RR相似,優先順序相同的執行緒也是迴圈排程。不過沒有時間片的概念。下面會詳細講解。
    2. 通用排程策略(非實時):spriority值為0.
      1. SCHED_OTHER:
      2. SCHED_IDLE:
      3. SCHED_BATCH:

所有的排程策略最後通過連結串列的方式組合成一個排程類。由linux核心排程。

各種排程策略介紹

  1. 實時排程策略之SCHED_RR:Round-robin scheduling
    1. 當執行緒間的優先順序不同時,優先順序高的先排程。當優先順序相同時,固定的時間片迴圈排程。被呼叫的執行緒滿足如下條件時會讓出CPU:
      1. 排程期間的時間片使用完了。
      2. 自動放棄CPU。如呼叫了阻塞相關的介面函式或呼叫了sched_yield()。
      3. 被一個優先順序更高的執行緒搶佔了
      4. 執行緒終止了。
    2. 如果因為時間片使用完了或自願放棄CPU而導致執行緒讓出CPU,此時此執行緒將會被放置在與其優 先級級別對應的佇列的隊尾。如果因為被搶佔而讓出CPU,則會放置到隊頭,等更高優先順序讓出cpu時,繼續執行此執行緒。
  2. 實時排程策略之SCHED_FIFO:First in-first out scheduling
    1. SCHED_RR實時排程策略相似,不過它沒有時間片的概念。被呼叫的執行緒讓出CPU條件與SCHED_RR類似,只是沒有時間片使用完的情況.
  3. 通用排程策略之SCHED_OTHER:time-sharing scheduling
    1. 分時迴圈排程策略。也就是我們常說的CFS(Completely Fair Scheduler)完全公平排程器。是系統的預設排程策略。按動態時間片迴圈排程。動態時間片nice屬性值決定。每個SCHED_OTHER策略的執行緒都擁有一個nice值,其取值範圍為−20~19,預設值為0.nice值是一個權重因子,值越小,權重越大。CPU為其分配的動態時間片會越多。
  4. 通用排程策略之SCHED_BATCH
    1. 此策略會讓頻繁被喚醒的執行緒在排程時次數會變少。其他與SCHED_OTHER策略類似。
  5. 通用排程策略之SCHED_IDLE
    1. 可以理解為nice=19的SCHED_OTHER策略。當系統中沒有其他執行緒需要使用CPU時才會大量使用CPU。
  6. 排程策略之SCHED_DEADLINE
    1. 自從3.14版本以來,Linux提供了一個截止日期排程策略(SCHED_DEADLINE)。

排程相關的使用者空間介面

修改nice值相關的函式介面:

  1. int nice(int inc)
    1. 所屬標頭檔案:<unistd.h>
    2. 描述:修改當前程序的nice值。此函式已經被更通用的setpriority()取代。
    3. inc:在當前nice的基礎上加inc.
    4. return: 如果成功,返回新設定的nice值。
    5. eg:nice(3)、nice(-5)
  2. int setpriority(int which, int who, int prio)
    1. 描述: 設定通用程序的nice值。這裡的priority不要與上邊講到的優先順序混淆。
    2. which:決定who傳入的引數含義,which可選值:
      1. PRIO_PROCESS:表明who為程序id.如果等於零,則為當前程序
      2. PRIO_PGRP:表明who為程序組id.如果等於零,則為當前程序組
      3. PRIO_USER:表明who為使用者(real user)id.如果等於零,則為當前使用者
    3. prio:-20~19之間的nice值。
    4. return: 成功返回0。失敗返回-1.。
  3. int getpriority(int which, int who)
    1. 所屬標頭檔案:<sys/time.h>,<sys/resource.h>
    2. 描述:獲取程序的nice值。
    3. return: 返回程序排程優先順序(-20~19)。
    4. eg: getpriority(PRIO_PROCESS, getpid());

修改優先順序與排程策略相關的函式介面:

  1. int sched_get_priority_max(int policy)
    1. 描述: 檢視排程策略最大優先順序。
    2. policy 可指定的值如下:
      1. SCHED_OTHER
      2. SCHED_BATCH
      3. SCHED_IDLE
      4. SCHED_FIFO
      5. SCHED_RR
    3. return: 成功返回最大優先順序值。失敗返回-1.
  2. int sched_get_priority_min(int policy)
    1. 檢視排程策略最小優先順序。其他同sched_get_priority_max().
  3. int sched_setscheduler(pid_t pid, int policy,const struct sched_param *param)
    1. 描述: 設定程序的排程策略和優先順序。
    2. policy 可指定的值如下:
      1. SCHED_OTHER
      2. SCHED_BATCH
      3. SCHED_IDLE 對於這三種策略,param->sched_priority的值必須為0.
      4. SCHED_FIFO
      5. SCHED_RR 對於這兩種策略,需要指定param->sched_priority的值。
    3. param:指定排程策略的優先順序。struct sched_param的結構體如下:
      struct sched_param {
          int sched_priority; //優先順序1~99
      };
      
    4. return: 成功返回0。失敗返回-1.
  4. int sched_getscheduler(pid_t pid)
    1. 所屬標頭檔案:<sched.h>
    2. 描述: 獲取程序的排程策略。
    3. pid 程序id.如果為0,表示為本執行緒。
    4. return: 成功返回排程策略值(非負整數)。失敗返回-1.
      1. SCHED_OTHER 0
      2. SCHED_FIFO 1
      3. SCHED_RR 2
      4. SCHED_BATCH 3
      5. SCHED_IDLE 5
  5. int sched_setparam(pid_t pid, const struct sched_param *param)
    1. 描述: 設定程序的優先順序。sched_setscheduler()函式的子集。
    2. param:見sched_setscheduler()函式中的描述。
    3. return: 成功返回0。失敗返回-1.
  6. int sched_getparam(pid_t pid, struct sched_param *param)
    1. 描述: 獲取程序的優先順序。
    2. param:見sched_setscheduler()函式中的描述。用於接收要獲取的優先順序值。
    3. return: 成功返回0。失敗返回-1.

linux特有的函式介面,可用於修改上邊提到的所有屬性:

  1. int sched_setattr(pid_t pid, struct sched_attr *attr,unsigned int flags)
    1. 描述: 設定程序的排程策略。
    2. struct sched_attr結構體如下:
      struct sched_attr {
             u32 size;              //結構體大小
             u32 sched_policy;      //排程策略
             u64 sched_flags;       //可選屬性:SCHED_FLAG_RESET_ON_FORK 表示子程序建立時不繼承此策略。
             s32 sched_nice;        //通用排程策略的nice值
             u32 sched_priority;    //優先順序
             /* Remaining fields are for SCHED_DEADLINE */
             u64 sched_runtime;
             u64 sched_deadline;
             u64 sched_period;
         };
      
    3. flags 目前為0.
    4. return: 成功返回0。
  2. int sched_getattr(pid_t pid, struct sched_attr *attr,unsigned int size, unsigned int flags)
    1. 描述: 獲取程序的排程策略。
    2. size: attr結構體的大小。
    3. 其他引數同sched_setattr().

其他介面:

  1. int sched_yield(void)
    1. 描述:程序主動放棄cpu.
  2. int sched_rr_get_interval(pid_t pid, struct timespec *tp)
    1. 獲取SCHED_RR排程策略的程序在每次使用CPU時分配到時間片的長度。
    2. tp:獲取到的時間長度。
    3. 成功返回0,失敗返回-1.

執行緒相關的排程設定函式:相關執行緒屬性設定。


關於技術交流

此處後的文字已經和題目內容無關,可以不看。
qq群:825695030
微信公眾號:嵌入式的日常
如果上面的文章對你有用,歡迎打賞、點贊、評論。二維碼