Linux内核API sched_setscheduler

sched_setscheduler函数功能描述:此函数用于改变进程的调度策略及进程的实时优先级。

sched_setscheduler文件包含

#include <linux/sched.h>

sched_setscheduler函数定义

在内核源码中的位置:linux-3.19.3/kernel/sched/core.c

函数定义格式:

int sched_setscheduler(struct task_struct * , int , const struct sched_param *)

sched_setscheduler输入参数说明

此函数的第一个参数是struct task_struct结构体类型的指针,保存进程的描述符信息,此结构体的定义较复杂,内核定义解释足够清晰,结构体定义参见文件linux-3.19.3/include/linux/sched.h。

此函数的第二个参数是int型的变量,代表设置的进程的新的调度策略,内核定义的取值如下:

#define SCHED_NORMAL       0        //普通进程调度策略
#define SCHED_FIFO         1        //用于软实时进程,先进先出调度策略
#define SCHED_RR           2        //用于软实时进程,循环调度策略
#define SCHED_BATCH        3        //非交互、CPU使用密集的批处理进程
#define SCHED_IDLE         5        //重要性比较低,不负责调度空闲进程

对于值为4的调度策略内核保留,但还没有实现。在此函数调用过程中合法的取值只能是1和2,对于其他的取值都是不合法的。

此函数的第三个参数是struct sched_param结构体类型的指针,保存设置进程的新的实时优先级,其定义见文件linux-3.19.3/include/linux/sched.h,如下:

struct sched_param {
    int sched_priority;           /*保存新的实时优先级值*/
};

其中进程的新的实时优先级值可能的取值是0~99,值越大代表的实时优先级越高,在此函数的调用过程中合法的取值范围是1~99。

sched_setscheduler返回参数说明

此函数的返回结果是int型的变量,可能的取值是0、-1、-22,其中返回0代表改变进程的policy和rt_priority的值成功,返回-1或-22代表改变进程的policy和rt_priority的值失败。

sched_setscheduler实例解析

编写测试文件:sched_setscheduler.c

头文件引用:

#include <linux/module.h>
#include <linux/sched.h>
#include <linux/pid.h>
MODULE_LICENSE("GPL");

子进程处理函数定义:

int my_function(void * argc)
{
    printk("in the kernel thread function! \n");
    printk("the policy of current thread is:%d\n", current->policy);
                                                          // 显示当前进程的policy值
    printk("the rt_priority of current thread is:%d\n", current->rt_priority);
                                                          // 显示当前进程的rt_priority值
    printk("the current pid is:%d\n", current->pid);      //显示当前进程的PID值
    printk("out the kernel thread function\n");
    return 0;
}

模块加载函数定义:

static int __init sched_setscheduler_init(void)
{
    /*局部变量定义*/
    struct task_struct * result;
    int result1;
    struct sched_param param;
    printk("into sched_setscheduler_init.\n");
    result=kthread_create_on_node(my_function, NULL, -1, "sched_setscheduler");
                                  // 创建新进程
    wake_up_process(result);

    param.sched_priority=100;     //设置字段sched_priority的值
    printk("the policy of the child thread is:%d\n", result->policy);
                                  // 显示新进程的policy的值
    printk("the rt_priority of the child thread is:%d\n", result->rt_priority);
                                  // 显示新进程的rt_priority的值
    result1=sched_setscheduler(result,1, &param);     //调用函数改变进程的调度策略
    printk("the new policy of the child thread is:%d\n", result->policy);
                                  // 显示函数调用之后新进程的policy的值
    printk("the new rt_priority of the child thread is:%d\n", result->rt_priority);
                                  // 显示函数调用之后新进程的rt_priority的值
    printk("the pid of new thread is :%d\n", result->pid);
                                  //显示函数kthread_create_on_node( )的返回结果pid
    printk("the result of the sched_setscheduler is:%d\n", result1);
                                  //显示函数sched_setscheduler( )的返回结果
    printk("the current pid is:%d\n", current->pid); //显示当前进程的PID值
    printk("out sched_setscheduler_init.\n");
    return 0;
}

模块退出函数定义:

static void __exit sched_setscheduler_exit(void)
{
    printk("Goodbye sched_setscheduler\n");
}

模块加载、退出函数调用:

module_init(sched_setscheduler_init);
module_exit(sched_setscheduler_exit);

实例运行结果及分析:

首先编译模块,执行命令insmod sched_setscheduler.ko插入内核模块,然后输入命令dmesg -c查看模块插入结果,会出现如图A所示的结果。

Linux内核API sched_setscheduler

更改输入参数的值,将模块加载函数中的语句“param.sched_priority=100; ”改为“param. sched_priority=1; ”,重编编译、加载模块,然后输入命令dmesg -c会出现如图B所示的结果。

Linux内核API sched_setscheduler

结果分析:

由图A可以得出此次函数调用设置进程的字段失败,返回结果是-22,设置进程的policy和rt_priority值失败,进程的此两个字段的值都没有发生任何改变,因为此时设置的进程的实时优先级值是100,100不合法。由图B可以得出此次函数调用设置进程的字段成功,函数调用返回结果是0,函数调用之后进程的policy和rt_priority字段的值都发生了改变。

在此字段policy的取值可能是1或2,1代表设置进程的调度策略为SCHED_FIFO;2代表设置进程的调度策略为SCHED_RR,如果传递的参数不是此二者中的一个,则函数调用设置进程的rt_priority和policy失败。

在此字段rt_priority的取值范围是1~99,值越大代表设置进程的实时优先级越大,如果传递的参数不在此范围内,则函数调用设置进程的rt_priority和policy失败。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程