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, ¶m); //调用函数改变进程的调度策略
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
所示的结果。
更改输入参数的值,将模块加载函数中的语句“param.sched_priority=100;
”改为“param. sched_priority=1; ”
,重编编译、加载模块,然后输入命令dmesg -c会出现如图B
所示的结果。
结果分析:
由图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失败。