Linux-进程调度相关的系统调用简介

前言

内核版本:2.6.26。

Linux提供了一个系统调用族,用于管理与调度程序相关的参数。这些系统调用可以用来操作和处理进程优先级、调度策略及处理器绑定。并且这些系统调用都包涵在C库中,也可用man手册查看。

与调度策略相关的系统调用

系统调用 描述
sched_getscheduler 获取进程的调度策略
sched_setscheduler 设置进程的调度策略和实时优先级

其函数原型如下:

#include <sched.h>

int sched_setscheduler(pid_t pid, int policy,
                              const struct sched_param *param);

int sched_getscheduler(pid_t pid);

参数说明:

参数 描述
pid 表示要修改/设置调度参数的目标线程,如果传入的参数pid为0则目标线程是调用该函数的线程;
policy 表示目标线程的调度策略。
param 它是一个结构指针类型。

补充:
目前linux对于sched_setscheduler()函数支持如下调度策略:

//include/linux/sched.h
/*
 * Scheduling policies
 */
#define SCHED_NORMAL	0   //标准的CFS调度策略;
#define SCHED_FIFO		1	//FIFO方式的实时调度策略
#define SCHED_RR		2	//轮转方式的实时调度策略
#define SCHED_BATCH		3	//针对"batch" 类型的任务,切换没有SCHED_OTHER频繁
/* SCHED_ISO: reserved but not implemented yet */
#define SCHED_IDLE		5	//适用于以低优先级运行的后台任务

SCHED_NORMAL、SCHED_BATCH、SCHED_IDLE都属于普通调度策略(非real-time调度策略),且采用上面三个policy其中一种时,第三个参数param->sched_priority必须设置为0,否则运行时会调用失败。

对于响应或者延迟有要求的任务可以通过SCHED_FIFO和SCHED_RR设置为实时调度策略。
param:是一个如下的结构指针类型:

struct sched_param {
    
    
               ...
               int sched_priority;
               ...
    }

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_setparam() 设置进程的实时优先级
sched_getparam() 获取进程的实时优先级
sched_get_priority_max() 获取实时进程的优先级的最大值
sched_get_priority_min() 获取实时进程的优先级的最小值

函数原型如下:

#include <sched.h>

int sched_get_priority_max(int policy);

int sched_get_priority_min(int policy);
int sched_setparam(pid_t pid, const struct sched_param *param);

int sched_getparam(pid_t pid, struct sched_param *param);

struct sched_param {
    
    
    ...
     int sched_priority;
    ...
};

#define MAX_USER_RT_PRIO	100
参数 描述
pid 表示要修改/设置调度参数的目标线程,如果传入的参数pid为0则目标线程是调用该函数的线程;
policy 表示目标线程的调度策略。
param 它是一个结构指针类型。

sched_setparam()与sched_getparam()这两个系统调用分别用于设置和获取进程的实时优先级。这两个系统调用获取封装在sched_param中的sched_priority。
sched_get_priority_max()与sched_get_priority_min()分别用于返回给定调度策略的最大和最小优先级。实时调度策略的最大优先级是MAX_USER_RT_PRIO - 1 (99),最小优先级等于1。

实例

#include <stdlib.h>             /* exit */
#include <stdio.h>              /* printf */
#include <sched.h>              /* sched_**** */
#include <sys/types.h>
#include <unistd.h>
 
int main(int argc, char *argv[])
{
    
    
    struct sched_param param;
    struct timespec tp;
    int maxFIFO,minFIFO,FIFO;
    int maxRR,minRR,RR;
    int Policy,ret;
    pid_t pid;

    printf("SCHED_NORMAL/SCHED_OTHER:\n");
    sleep(5);
    pid = getpid();
    Policy = sched_getscheduler(pid);
    printf ("调度策略为 : %d\n", Policy);
    if(Policy == 0){
    
    
        printf("当前进程调度策略为标准的CFS调度策略(SCHED_NORMAL/SCHED_OTHER)\n");
    }

    
    //SCHED_FIFO
    printf("\n");
    printf("SCHED_FIFO:\n");
    maxFIFO = sched_get_priority_max(SCHED_FIFO);
    minFIFO = sched_get_priority_min(SCHED_FIFO);
	printf("FIFO max priority is : %d\n", maxFIFO);
    printf("FIFO min priority is : %d\n", minFIFO);
    if(maxFIFO == -1 || minFIFO == -1){
    
    
        perror("sched_get_priority_max/min() error!\n");
        exit(1);
    }
    param.sched_priority = maxFIFO;
    if(sched_setscheduler(pid, SCHED_FIFO, &param) == -1){
    
    
        perror("sched_setscheduler() error!\n");
        exit(1);
    }
    Policy = sched_getscheduler(pid);
    printf ("调度策略为 : %d\n", Policy);
    sleep(5);
    FIFO = sched_getparam(pid , &param);
    if(FIFO == 0){
    
    
        printf ("进程的实时优先级为 : %d\n",param.sched_priority);
    }
    param.sched_priority = 80;
    ret = sched_setparam(pid , &param);
    FIFO = sched_getparam(pid , &param);
    if(FIFO == 0){
    
    
        printf ("修改后进程的实时优先级为 : %d\n",param.sched_priority);
    }
    
    
    //SCHED_RR
    printf("\n");
    printf("SCHED_RR:\n");
    maxRR = sched_get_priority_max(SCHED_RR);
    minRR = sched_get_priority_min(SCHED_RR);
	printf("RR max priority is : %d\n", maxRR);
    printf("RR min priority is : %d\n", minRR);
    if(maxRR == -1 || minRR == -1){
    
    
        perror("sched_get_priority_max/min() error!\n");
        exit(1);
    }

    param.sched_priority = minRR;
    if(sched_setscheduler(pid, SCHED_RR, &param) == -1){
    
    
        perror("sched_setscheduler() error!\n");
        exit(1);
    }
    ret = sched_rr_get_interval(pid,&tp);
    if(ret == 0){
    
    
        printf("当前进程的时间片为:%lds  %ldns\n",tp.tv_sec,tp.tv_nsec);
    }
    Policy = sched_getscheduler(pid);
    printf ("调度策略为 : %d\n", Policy);
    sleep(5);
    RR = sched_getparam(pid , &param);
    if(RR == 0){
    
    
        printf ("进程的实时优先级为 : %d\n",param.sched_priority);
    }

    return 0;
}


运行结果如下:
请添加图片描述

猜你喜欢

转载自blog.csdn.net/weixin_45309916/article/details/127218316