更改流程优先级
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);
基于
问题是我想在程序 运行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);