如何使用SIGSTOP和SIGCONT强制一个过程以CPU使用的指定百分比运行?
我编写了一个简单的C程序,以强制使用Sigstop和Sigcont在CPU使用的特定百分比下运行的过程。但是%cpu
topCommand显示它始终超过设置编号。如何强制程序运行%CPU
不超过指定值?
图像Bellow显示将限制设置为20%时获得的内容,Process loop
使用%CPU = 21.3
:
github,运行测试以在项目的根文件夹中启动测试实例:
https:> https://github.com/zltl/ CPU_LIMIT_RUN
代码是计算当前CPU流程时间的程序的主要循环,并发送sigstop或sigcond以达到限制:
// we store time stats of process in a circular queue array, each element store
// a struct time_history.
struct time_history {
long utime, stime, cutime, cstime;
long long total_cpu_usage;
};
#define MAX_HISTORY_LEN 30
struct time_history time_history[MAX_HISTORY_LEN];
int cur_history_idx = 0;
#define MAX_PATH_LEN 256
// main loop, calculate current cpu time of process, send SIGSTOP or SIGCOND to
// satisfy the limit.
int loop(struct my_conf *conf) {
char stat_file[MAX_PATH_LEN];
long nproc = get_nprocs();
long long p_total_cpu_usage = 0;
long p_utime, p_stime, p_cutime, p_cstime;
long utime, stime, cutime, cstime;
long long starttime;
int full = 0;
int is_stop = 0;
sprintf(stat_file, "/proc/%d/stat", conf->pid);
for (;;) {
long long total_cpu_usage = get_total_cpu_usage();
FILE *fp = fopen(stat_file, "r");
if (fp == NULL) {
fprintf(stdout, "pid %d exited %s\n", conf->pid, strerror(errno));
return -1;
}
fscanf(fp,
"%*d %*s %*c %*d " // pid,command,state,ppid
"%*d %*d %*d %*d %*u %*u %*u %*u %*u "
"%ld %ld %ld %ld " // utime,stime,cutime,cstime
"%*d %*d %*d %*d "
"%lld",
&utime, &stime, &cutime, &cstime, &starttime);
fclose(fp);
struct time_history *th = &time_history[cur_history_idx];
th->utime = utime;
th->stime = stime;
th->cutime = cutime;
th->cstime = cstime;
th->total_cpu_usage = total_cpu_usage;
cur_history_idx++;
if (cur_history_idx >= MAX_HISTORY_LEN) {
cur_history_idx = 0;
full = 1;
}
if (!full) {
usleep(1000L * conf->interval_ms);
continue;
}
struct time_history *th_prev = &time_history[cur_history_idx];
p_utime = th_prev->utime;
p_stime = th_prev->stime;
p_cutime = th_prev->cutime;
p_cstime = th_prev->cstime;
p_total_cpu_usage = th_prev->total_cpu_usage;
long long proc_time_since = utime - p_utime + stime - p_stime + cutime -
p_cutime + cstime - p_cstime;
long long total_time_since = total_cpu_usage - p_total_cpu_usage;
//********** calculate, send signals ***************
double cpu_usage =
(proc_time_since * (double)100.0) / total_time_since * nproc;
if (cpu_usage >= conf->percent && !is_stop) {
kill(conf->pid, SIGSTOP);
is_stop = 1;
}
if (cpu_usage < conf->percent && is_stop) {
kill(conf->pid, SIGCONT);
is_stop = 0;
}
//*************************
usleep(1000L * conf->interval_ms);
}
}
I wrote a simple C program to force a process to run under a specific percent of cpu usage using SIGSTOP and SIGCONT. But %CPU
of topcommand shows it always exceed the setting number a little bit. How can I force the program run with %CPU
not exceed the specified value?
The image bellow shows what I get when setting the limit to 20%, process loop
run with %CPU=21.3
:
Source codes upload on github, run make test to start a testing instance inside the project's root folder:
https://github.com/zltl/cpu_limit_run
Codes fllow are main loop of the program that calculates current cpu time of process, and send SIGSTOP or SIGCOND to attain the limit:
// we store time stats of process in a circular queue array, each element store
// a struct time_history.
struct time_history {
long utime, stime, cutime, cstime;
long long total_cpu_usage;
};
#define MAX_HISTORY_LEN 30
struct time_history time_history[MAX_HISTORY_LEN];
int cur_history_idx = 0;
#define MAX_PATH_LEN 256
// main loop, calculate current cpu time of process, send SIGSTOP or SIGCOND to
// satisfy the limit.
int loop(struct my_conf *conf) {
char stat_file[MAX_PATH_LEN];
long nproc = get_nprocs();
long long p_total_cpu_usage = 0;
long p_utime, p_stime, p_cutime, p_cstime;
long utime, stime, cutime, cstime;
long long starttime;
int full = 0;
int is_stop = 0;
sprintf(stat_file, "/proc/%d/stat", conf->pid);
for (;;) {
long long total_cpu_usage = get_total_cpu_usage();
FILE *fp = fopen(stat_file, "r");
if (fp == NULL) {
fprintf(stdout, "pid %d exited %s\n", conf->pid, strerror(errno));
return -1;
}
fscanf(fp,
"%*d %*s %*c %*d " // pid,command,state,ppid
"%*d %*d %*d %*d %*u %*u %*u %*u %*u "
"%ld %ld %ld %ld " // utime,stime,cutime,cstime
"%*d %*d %*d %*d "
"%lld",
&utime, &stime, &cutime, &cstime, &starttime);
fclose(fp);
struct time_history *th = &time_history[cur_history_idx];
th->utime = utime;
th->stime = stime;
th->cutime = cutime;
th->cstime = cstime;
th->total_cpu_usage = total_cpu_usage;
cur_history_idx++;
if (cur_history_idx >= MAX_HISTORY_LEN) {
cur_history_idx = 0;
full = 1;
}
if (!full) {
usleep(1000L * conf->interval_ms);
continue;
}
struct time_history *th_prev = &time_history[cur_history_idx];
p_utime = th_prev->utime;
p_stime = th_prev->stime;
p_cutime = th_prev->cutime;
p_cstime = th_prev->cstime;
p_total_cpu_usage = th_prev->total_cpu_usage;
long long proc_time_since = utime - p_utime + stime - p_stime + cutime -
p_cutime + cstime - p_cstime;
long long total_time_since = total_cpu_usage - p_total_cpu_usage;
//********** calculate, send signals ***************
double cpu_usage =
(proc_time_since * (double)100.0) / total_time_since * nproc;
if (cpu_usage >= conf->percent && !is_stop) {
kill(conf->pid, SIGSTOP);
is_stop = 1;
}
if (cpu_usage < conf->percent && is_stop) {
kill(conf->pid, SIGCONT);
is_stop = 0;
}
//*************************
usleep(1000L * conf->interval_ms);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您可以使用Linux NICE命令 - 运行具有修改的计划优先级程序的方法
You can use the linux nice command - a method to run a program with modified scheduling priority