天天看點

linux 任務排程 sched_setscheduler

sched_setscheduler()函數用以修改線程的排程政策以及排程參數。

一 函數原型

#include <sched.h>
int sched_setscheduler(pid_t pid, int policy, const struct sched_param *param);      

二 參數說明

pid:表示要修改/設定排程參數的目标線程,如果傳入的參數pid為0則目标線程是調用該函數的線程;

policy: 表示目标線程的排程政策。目前linux對于sched_setscheduler()函數支援如下排程政策:

1) SCHED_OTHER   标準的CFS排程政策;
2) SCHED_BATCH   針對"batch" 類型的任務,切換沒有SCHED_OTHER頻繁;
3) SCHED_IDLE    适用于以低優先級運作的背景任務。      

上面三個任務都屬于普通排程政策(非real-time排程政策),且采用上面三個policy其中一種時,第三個參數param->sched_priority必須設定為0,否則運作時會調用失敗。

4) SCHED_FIFO    FIFO方式的實時排程政策;

5) SCHED_RR      輪轉方式的實時排程政策。      

對于響應或者延遲有要求的任務可以通過SCHED_FIFO和SCHED_RR設定為實時排程政策。

sched_param 的結構體如下:

#include <sched.h>
 
struct sched_param 
{ 
    int32_t  sched_priority; 
    int32_t  sched_curpriority; 
    union 
    { 
        int32_t  reserved[8]; 
        struct 
        {    
            int32_t  __ss_low_priority;  
            int32_t  __ss_max_repl;  
            struct timespec     __ss_repl_period;   
            struct timespec     __ss_init_budget;   
        }           __ss;   
    }           __ss_un;    
}
 
#define sched_ss_low_priority   __ss_un.__ss.__ss_low_priority
#define sched_ss_max_repl       __ss_un.__ss.__ss_max_repl
#define sched_ss_repl_period    __ss_un.__ss.__ss_repl_period
#define sched_ss_init_budget    __ss_un.__ss.__ss_init_budget      

Param->sched_priority用以指定目标線程的優先級,這也是sched_setscheduler()函數對于param比較普遍的用法。

傳回值:

函數調用成功時傳回0;而失敗或者出錯時傳回-1,并設定errno值。下面是失敗時,設定不同errno的情況:

EINVAL: 無效參數。Pid小于0或者param 為 NULL;

EINVAL: 參數policy 不是上面提到的幾種,無法識别;

EINVAL: 參數param(或者param結構中的值)對于指定的policy無意義;

EPERM : 函數調用者沒有權限;

ESRCH : 傳入的pid不存在。

三 線程的排程有三種政策

線程的排程有三種政策:SCHED_OTHER、SCHED_RR和SCHED_FIFO。下面我們簡單的說明一下這三種排程政策。

SCHED_OTHER

它是預設的線程分時排程政策,所有的線程的優先級别都是0,線程的排程是通過分時來完成的。簡單地說,如果系統使用這種排程政策,程式将無法設定線程的優先級。請注意,這種排程政策也是搶占式的,當高優先級的線程準備運作的時候,目前線程将被搶占并進入等待隊列。這種排程政策僅僅決定線程在可運作線程隊列中的具有相同優先級的線程的運作次序。

SCHED_FIFO

它是一種實時的先進先出調用政策,且隻能在超級使用者下運作。這種調用政策僅僅被使用于優先級大于0的線程。它意味着,使用SCHED_FIFO的可運作線程将一直搶占使用SCHED_OTHER的運作線程J。此外SCHED_FIFO是一個非分時的簡單排程政策,當一個線程變成可運作狀态,它将被追加到對應優先級隊列的尾部((POSIX 1003.1)。當所有高優先級的線程終止或者阻塞時,它将被運作。對于相同優先級别的線程,按照簡單的先進先運作的規則運作。我們考慮一種很壞的情況,如果有若幹相同優先級的線程等待執行,然而最早執行的線程無終止或者阻塞動作,那麼其他線程是無法執行的,除非目前線程調用如pthread_yield之類的函數,是以在使用SCHED_FIFO的時候要小心處理相同級别線程的動作。