转载:http://q928856957.blog.163.com/blog/static/250560062201561554437668/
很多公司都会对机器资源做监控,长期闲置的机器需要回收,再合理分配,提升资源的利用率,从公司层面讲无可厚非。
但存在一个问题,资源还回去之后,很多时候再申请就难,所以很多时候为了留住资源,就需要制造一种虚假繁荣,那就是让机器的CPU一直处于高利用率。
解决这个问题的思路是控制CPU的忙闲时间比例。
下面的代码实现在一台比较空闲的机器上,如何控制CPU的利用率。
/*
* @file : kcpu.c
* @author : sunnyChan
* @date : 2015/03/23
* */
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <string.h>
#include <sys/time.h>
/* 设置一个统计的时间跨度 */
/* 如果CPU统计工具统计每秒的CPU使用率,INTERVAL 最好设置为1000ms */
#define INTERVAL 100
double get_time();
void print_usage();
double get_time()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return (tv.tv_sec * 1000 + tv.tv_usec * 1.0 / 1000); /* ms */
}
void print_usage()
{
printf("usage : kcpu -r 50 \n");
printf("options : \n");
printf(" -r specify cpu usage rate.\n");
printf("\n");
}
int main(int argc, char *argv[])
{
/* 解析和校验参数 */
if (argc != 3) {
printf("error : parameters error.\n");
print_usage();
exit(1);
}
int cpu_rate = 0; /* CPU 使用率 */
if (strcmp(argv[1], "-r") == 0) {
cpu_rate = atoi(argv[2]);
if ((cpu_rate <= 0) || (cpu_rate > 100)) {
printf("error : specify cpu usage rate error.\n");
exit(1);
}
} else {
printf("error : parameters error.\n");
print_usage();
exit(1);
}
/* 根据设置的CPU使用率 计算CPU被占用时间 和 CPU空闲时间 */
double busy_span = INTERVAL * cpu_rate / 100;
double idle_span = INTERVAL * (100 - cpu_rate) / 100;
double start_time; /* 每次统计时段的开始时间,Unix 时间戳,单位ms */
while (1) {
/* 获取当前Unix 时间戳,计算到ms */
start_time = get_time();
/* 接下来的 busy_span 长的时间使CPU处于忙碌 */
while ((get_time() - start_time) <= busy_span);
/* 接下来的 idle_span 长的时间使CPU处于空闲 */
usleep(idle_span * 1000);
}
return 0;
}
现在的服务器大多是SMP(多CPU)架构,这种情况下可以将上述程序改成多线程并发,当然线程个数要等于CPU的线程数,另外也可以Shell 运行多个进程来实现。
#!/bin/bash
# 设置CPU使用率
CPU_RATE="70"
# 由kcpu.c编译后的二进制文件名
BIN_NAME="kcpu"
# 根据CPU的数目,启动相应个数的工具进程
function start_kcpu()
{
#获取当前机器上的CPU线程数
cpu_count=$(grep -c "processor" /proc/cpuinfo)
#根据CPU线程数,启动相应的进程数
for ((i=0;i<${cpu_count};i++))
do
( ./kcpu -r ${CPU_RATE} & )
done
echo "Done!"
}
while [ $# -gt 0 ]
do
case "X$1" in
Xstart)
start_kcpu
;;
Xstop)
ps -u ${USER} | grep "${BIN_NAME}" | awk '{print "kill -KILL "$1}' |sh
;;
*)
echo "Error : parameters error"
echo "Usage : sh run_kcpu.sh [start|stop]"
exit 1
;;
esac
shift 1
done
以上程序需要在空闲的机器上运行,才能比较精确地获取到设置的CPU利用率。
如果机器上有其他CPU消耗型的进程在运行,CPU实际的利用率会比设定的值要高。
这种情况下如果想要精确的控制CPU的使用率很难,因为很难知道其它进程接下来的一个统计时段里将怎样使用CPU。
一种比较接近的思路是参考过去一段时间内CPU的利用情况,当然这种处理方式下误差肯定是存在的。