前言
内核版本: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, ¶m) == -1){
perror("sched_setscheduler() error!\n");
exit(1);
}
Policy = sched_getscheduler(pid);
printf ("调度策略为 : %d\n", Policy);
sleep(5);
FIFO = sched_getparam(pid , ¶m);
if(FIFO == 0){
printf ("进程的实时优先级为 : %d\n",param.sched_priority);
}
param.sched_priority = 80;
ret = sched_setparam(pid , ¶m);
FIFO = sched_getparam(pid , ¶m);
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, ¶m) == -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 , ¶m);
if(RR == 0){
printf ("进程的实时优先级为 : %d\n",param.sched_priority);
}
return 0;
}
运行结果如下: