set_user_nice函数功能描述:此函数用于设置进程的nice值,其实nice值的计算是根据进程的静态优先级,所以此函数用于更改进程的静态优先级。在更改进程的静态优先级的同时,会检查此进程是否可以被调度,当条件满足时,将调度该进程,当进程被调度后将恢复系统默认的普通进程的静态优先级及nice值。
set_user_nice文件包含
#include <linux/sched.h>
set_user_nice函数定义
在内核源码中的位置:linux-3.19.3/kernel/sched/core.c
函数定义格式:
void set_user_nice(struct task_struct *p, long nice)
set_user_nice输入参数说明
- 此函数的第一个参数是进程描述符信息,其定义比较复杂,在内核定义中关于此参数说明比较详细,具体定义参见内核源码文件linux-3.19.3/include/linux/sched.h。
- 此函数的第二个参数是设置的nice的值,进程的nice的值将被设置为参数nice的值,虽然nice是long型的变量,但其有效的取值范围是-20~19,如果参数nice的值不在此范围之内,则此函数将不会对进程的优先级做任何的改变。
set_user_nice返回参数说明
此函数不返回任何类型的值。
set_user_nice实例解析
编写测试文件:set_user_nice.c
头文件引用:
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/pid.h>
#include <linux/kthread.h>
MODULE_LICENSE("GPL");
子进程处理函数定义:
int my_function(void * argc)
{
printk("in the kernel thread function! \n");
printk("the current static_prio is:%d\n", current->static_prio);
// 显示当前进程的静态优先级
printk("the current nice is:%d\n", task_nice(current)); //获取当前进程的nice值
printk("the current pid is:%d\n", current->pid); //显示当前进程的PID值
printk("out the kernel thread function\n");
return 0;
}
模块加载函数定义:
static int __init set_user_nice_init(void)
{
struct task_struct * result;
printk("into set_user_nice_init.\n");
result=kthread_create_on_node(my_function, NULL, -1, "set_user_nice"); // 创建新进程
wake_up_process(result);
printk("the static_prio of the child thread is:%d\n", result->static_prio);
// 显示新进程的静态优先级
printk("the nice of the child thread is:%d\n", task_nice(result));
// 获取新进程的nice值
printk("the prio of the child thread is:%d\n", result->prio);
// 显示新进程的动态优先级
set_user_nice(result, -20); //设置新进程的nice值
// set_user_nice(result,19);
// set_user_nice(result, -21);
// set_user_nice(result,20);
printk("the new value static_prio of the child thread is:%d\n", result->static_prio);
// 显示新进程的静态优先级
printk("the new value nice of the child thread is:%d\n", task_nice(result));
// 显示新进程的nice值
printk("the pid of new thread is :%d\n", result->pid);
//显示kthread_create_on_node( )函数的返回结果
printk("the current pid is:%d\n", current->pid); //显示当前进程的PID值
printk("out set_user_nice_init.\n");
return 0;
}
模块退出函数定义:
static void __exit set_user_nice_exit(void)
{
printk("Goodbye set_user_nice\n");
}
模块加载、退出函数调用:
module_init(set_user_nice_init);
module_exit(set_user_nice_exit);
实例运行结果及分析:
首先编译模块,执行命令insmod set_user_nice.ko插入内核模块,然后输入命令dmesg -c查看内核输出信息,出现如图A
所示的结果。
执行命令rmmod set_user_nice.ko删除模块,然后更改参数nice的值为19,重新编译文件,执行命令insmod set_user_nice.ko重新插入模块,执行命令dmesg -c出现如图B
所示的结果。
执行命令rmmod set_user_nice.ko删除模块,然后更改参数nice的值为-21或20,重新编译模块,执行命令insmod set_user_nice.ko加载模块,执行命令dmesg -c会出现如图C
所示的结果。
结果分析:
由图A
~图C
可以看出,刚创建的新进程其静态优先级是120,其nice值为0,动态优先级与静态优先级相同也是120。通过函数set_user_nice( )作用之后,进程的静态优先级和nice值都发生了变化,nice的值变为参数nice的值,静态优先级变为原静态优先级与参数nice值的和,其中参数nice的值的有效范围是-20~19,如果nice的值不在此范围之内则进程的nice值及静态优先级都不会发生变化,由图C
可以明显看出。
进程的优先级说明:
进程的优先级分为静态优先级、动态优先级。静态优先级是进程在创建之初就分配的值,动态优先级是会随着进程在内核的时间而改变的,动态优先级是内核进行进程调度参考的依据,与内核的进程调度策略有关。对于普通进程和实时进程的优先级在task_struct结构体中字段normal_priority用于区别,是根据进程的静态优先级和进程的调度策略计算出的优先级,所以即使普通进程的静态优先级和实时进程的静态优先级相同,其普通优先级normal_priority也不会相同。
对于静态优先级其取值范围是100~139,数值越大其优先级越小,nice的值的范围是-20~19, nice值与静态优先级的转换公式是static_prio=120+nice。