更改流程优先级

Changing process priorities

基于 ,我想根据 RAM 使用情况更改进程优先级。我完全清楚这并不总是更改优先级的最佳方式,但这仅适用于一个项目。我正在尝试使用 renice 和 execvp 来设置进程优先级。

问题是我想在程序 运行ning 时启动带有附加参数的 renice 以更改进程优先级。问题是,当我 运行 使用正确的 #include 执行 execvp 时,它会弹回一个有很多依赖项的错误。

我的 main.c 有两个数组。一个有进程 ID,另一个有相应的 RAM 使用情况,它们按降序排列。有什么方法可以使用此信息更改进程优先级吗?

main.c

#include </usr/include/asm-generic/unistd.h>        //execvp:
#include <linux/kernel.h>      // printk(), pr_*()
#include <linux/module.h>      // THIS_MODULE, MODULE_VERSION, ...
#include <linux/init.h>        // module_{init,exit}
#include <linux/sched/task.h>  // struct task_struct, {get,put}_task_struct()
#include <linux/mm.h>          // get_mm_rss()
#include <linux/pid.h>         // struct pid, get_pid_task(), find_get_pid()
#include <linux/moduleparam.h> // module_param_named()
#include <linux/slab.h>
struct task_struct *task;        /*    Structure defined in sched.h for tasks/processes    */
/*
 * Power Services: 80-51%
 * renice -n 5 -p [pid] //(20-5)/20 = 75% of CPU
 * Standard Services: 50-26%
 * renice -n 10 -p [pid] //(20-10)/20 = 50% of CPU
 * Optimized Services: 1-25%
 * renice -n 15 -p [pid] //(20-15)/20 = 25% of CPU
 */
/*
static char *envp[] = {
"SHELL=/bin/bash",
"HOME=/bin/admin0",
"USER=admin",
"PATH=/home/admin/bin:/home/admin/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/admin",
"DISPLAY=:0",
"PWD=/home/admin",
NULL};
*/
typedef struct 
{
  int *array;
  size_t used;
  size_t size;
} id_array;

typedef struct 
{
  unsigned long *array;
  size_t used;
  size_t size;
} ram_array;

int rss = 0;
int counter = 0;//Iterator for arrays
//Change according to available memory size
int highLimit =322122547; //3GB
int mediumLimit=214748364;//2GB
int lowLimit= 107374182;//1GB

//The RAM usage and process ID data types are different and require different argument types
void initArray(id_array *a, size_t initialSize);
void insertArray(id_array *a, int element);
void initarray(ram_array *a, size_t initialSize);
void insertarray(ram_array *a, long unsigned element);

 // Function to swap the the position of two elements
void swapper(long unsigned *a, long unsigned *b);
  
void id_swap(int *a, int *b);//Swap IDs when sorting
  
void heapify(unsigned long* arr, int n, int i, int *id);
  
  // Main function to do heap sort
void heapSort(ram_array *a, id_array *b);

id_array pid;
ram_array ram;

int iterate_init(void)                    /*    Init Module    */
{

    printk(KERN_INFO "%s","LOADING MODULE\n");    /*    good practice to log when loading/removing modules    */
     

    
    initArray(&pid, 1);
    initarray(&ram, 1);
    for_each_process( task ) //Loop through all the processes to count how many there are. This function is located in linux\sched\signal.h
    {
        get_task_struct(task);
        insertArray(&pid, task->pid);   
        if(task->mm)
        {
            rss = get_mm_rss(task->mm) << PAGE_SHIFT;
        insertarray(&ram, rss);
        }
        else
        {
            insertarray(&ram, 0);
        }         
        counter++;
        put_task_struct(task);
    }    



    counter = 0;
    heapSort(&ram, &pid);
    while(counter < ram.used)
    {
        printk("Process %i: %lu bytes of RAM, Priority: %i\n", pid.array[counter], ram.array[counter], counter + 1);//Remember to put a \n at the end of each printk call, or your formatting can get messed up.
        
        //Modifying Priority Engine  
        if (ram.array[counter] < mediumLimit){
            printk("Process %i is a Optimized Process!!\n", pid.array[counter]);
            char param;
            param= "/usr/bin/renice -n 15 -p " + pid.array[counter];  
            char *args[3]={"/usr/bin/renice", param, NULL};
            execvp("/usr/bin/renice", args);
          }
        else if (ram.array[counter] > mediumLimit && ram.array[counter] < highLimit){
            printk("Process %i is a Standard Process!!\n", pid.array[counter]);
            //param= "renice -n 10 -p " + pid.array[counter];  
            //char *args[3]={"renice", param, NULL};
            //execvp("renice", args);
        }
        else {
            printk("Process %i is a Power Process!!\n", pid.array[counter]);
            //param= "renice -n 5 -p " + pid.array[counter];  
            //char *args[3]={"renice", param, NULL};
            //execvp("renice", args);
        }
        counter++;
        
    }
    
    return 0;
 
}                /*    End of Init Module    */



 // Function to swap the the position of two elements
void swapper(long unsigned *a, long unsigned *b) 
{
    int temp = *a;
    *a = *b;
    *b = temp;
}
  
void id_swap(int *a, int *b) 
{
    int temp = *a;
    *a = *b;
    *b = temp;
}
  
void heapify(unsigned long* arr, int n, int i, int *id) 
{
    // Find smallest among root, left child and right child
    int smallest = i;
    int left = 2 * i + 1;
    int right = 2 * i + 2;
  
    if (left < n && arr[left] < arr[smallest])
      smallest = left;
  
    if (right < n && arr[right] < arr[smallest])
      smallest = right;
  
    // Swap and continue heapifying if root is not largest
    if (smallest != i) {
      swapper(&arr[i], &arr[smallest]);
      id_swap(&id[i], &id[smallest]);//Switch corresponding ID with its RAM usage.
      heapify(arr, n, smallest, id);
    }
}
  
  // Main function to do heap sort
void heapSort(ram_array *a, id_array *b) 
{
    // Build max heap
    int i = a->used / 2 - 1;
    while(i >= 0)
    {
        heapify(a->array, a->used, i, b->array);
        i--;
    }

    i = a->used - 1;  
    // Heap sort
    while(i >= 0)
    {
        swapper(&a->array[0], &a->array[i]);
        id_swap(&b->array[0], &b->array[i]);//Switch corresponding ID with its RAM usage.
        // Heapify root element to get highest element at root again
        heapify(a->array, i, 0, b->array);
        i--;
    }

}



void initArray(id_array *a, size_t initialSize) 
{
  a->array = kvmalloc(initialSize * sizeof(int), GFP_KERNEL);
  a->used = 0;
  a->size = initialSize;
}

void insertArray(id_array *a, int element) 
{
  // a->used is the number of used entries, because a->array[a->used++] updates a->used only *after* the array has been accessed.
  // Therefore a->used can go up to a->size 
  if (a->used == a->size) {
    a->size *= 2;
    a->array = krealloc(a->array, a->size * sizeof(int), GFP_KERNEL);
  }
  a->array[a->used++] = element;
}

     
void initarray(ram_array *a, size_t initialSize) 
{
  a->array = kvmalloc(initialSize * sizeof(unsigned long), GFP_KERNEL);
  a->used = 0;
  a->size = initialSize;
}

void insertarray(ram_array *a, unsigned long element) 
{
  // a->used is the number of used entries, because a->array[a->used++] updates a->used only *after* the array has been accessed.
  // Therefore a->used can go up to a->size 
  if (a->used == a->size) {
    a->size *= 2;
    a->array = krealloc(a->array, a->size * sizeof(unsigned long), GFP_KERNEL);
  }
  a->array[a->used++] = element;
}    
     
     
   
     
     
void cleanup_exit(void)        /*    Exit Module    */
{
 
 
    printk(KERN_INFO "%s","REMOVING MODULE\n");
 
}                /*    End of Exit Module    */


module_init(iterate_init);    /*    Load Module MACRO    */
module_exit(cleanup_exit);    /*    Remove Module MACRO    */
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("ITERATE THROUGH ALL PROCESSES/CHILD PROCESSES IN THE OS");
MODULE_AUTHOR("G8C");

生成文件

obj-m += main.o test.o
run:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
    sudo insmod main.ko
    sleep 3s
    sudo rmmod main
    sudo dmesg -c
all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

我进行了更多挖掘,发现了一些有用的函数。

包括这些:

#include <linux/resource.h>
#include <linux/time.h>
#include <linux/sched.h>

然后,如果你想查看一些只有进程 ID 的信息:

struct task_struct *p;

        p = pid_task(find_vpid(pid), PIDTYPE_PID);//task structure of related p_id
        int y = p->prio;//priority of the process

或者如果您只想设置优先级(set_user_nice 实际上实时更改优先级,而不仅仅是 nice 值):

set_user_nice(p, long_int_nice_value);