Linux内核API set_user_nice

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所示的结果。

Linux内核API set_user_nice

执行命令rmmod set_user_nice.ko删除模块,然后更改参数nice的值为19,重新编译文件,执行命令insmod set_user_nice.ko重新插入模块,执行命令dmesg -c出现如图B所示的结果。

Linux内核API set_user_nice

执行命令rmmod set_user_nice.ko删除模块,然后更改参数nice的值为-21或20,重新编译模块,执行命令insmod set_user_nice.ko加载模块,执行命令dmesg -c会出现如图C所示的结果。

Linux内核API set_user_nice

结果分析:

由图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。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程