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的时候要小心处理相同级别线程的动作。

SCHED_RR

鉴于SCHED_FIFO调度策略的一些缺点,SCHED_RR对SCHED_FIFO做出了一些增强功能。从实质上看,它还是SCHED_FIFO调用策略。它使用最大运行时间来限制当前进程的运行,当运行时间大于等于最大运行时间的时候,当前线程将被切换并放置于相同优先级队列的最后。这样做的好处是其他具有相同级别的线程能在“自私“线程下执行。

`sched_setscheduler` 是 Linux 系统调度程序的一个函数,它允许进程设置自己的调度策略和优先级。该函数可以用于实时进程或非实时进程。它的原型如下: ```c int sched_setscheduler(pid_t pid, int policy, const struct sched_param *param); ``` 其中,`pid` 是要设置的进程的 ID,`policy` 是调度策略,可以是 `SCHED_FIFO`、`SCHED_RR` 或 `SCHED_OTHER` 中的一个,`param` 是一个指向 `sched_param` 结构的指针,包含了进程的优先级等信息。 - `SCHED_FIFO`:先进先出调度策略。进程按照它们加入运行队列的顺序进行调度。如果一个进程一直保持在运行状态,那么它将一直占用 CPU 资源,其他进程可能得不到运行机会。 - `SCHED_RR`:时间片轮转调度策略。每个进程被分配一个时间片,当时间片用完后,进程被放回队列尾部,等待下一次调度。这种策略确保每个进程都有机会执行,并且可以防止某个进程长时间占用 CPU。 - `SCHED_OTHER`:普通调度策略。这是默认的调度策略,它不保证任何特定的调度行为。 `param` 结构包含了以下字段: ```c struct sched_param { int sched_priority; // 进程优先级 }; ``` `sched_priority` 字段用于设置进程的优先级。在 `SCHED_FIFO` 和 `SCHED_RR` 策略中,较高的优先级意味着进程更容易获得 CPU 时间片。在 `SCHED_OTHER` 策略中,该值不起作用。 调用 `sched_setscheduler` 函数后,相应的进程将按照指定的调度策略和优先级进行运行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值