题目:写一个程序,让用户来决定Windows任务管理器(Task Manager)的CPU占用率。程序越精简越好,计算机语言不限。例如,可以实现下面三种情况:

1. CPU的占用率固定在50%,为一条直线;

2. CPU的占用率为一条直线,但是具体占用率由命令行参数决定(参数范围1~ 100);

3. CPU的占用率状态是一个正弦曲线。

控制CPU占用率,不仅仅是出于好玩而已。以前的某些程序,特别是某些老游戏,在新的机器上运行速度太快,必须先给CPU降速,才能顺利运行那些程序,有个共享软件CPUKiller,就是专门弄这个的。

控制CPU占用率,因为要调用Windows的API,要考虑到多核、超线程的情况,要考虑到不同版本的Windows的计时相关的API的精度不同,使问题变得相当复杂,若再考虑其它程序的CPU占用率,则该问题则变得很烦人。(taskmgr调用了一个未公开的API)。

对CPU核数的判断,书上是调用GetProcessorInfo,其实可以直接调用GetSystemInfo,SYSTEM_INFO结构的dwNumberOfProcessors成员就是核数。不知道超线程对这两种方法有什么影响。

如果不考虑其它程序的CPU占用情况,可以在每个核上开一个线程,运行指定的函数,实现每个核的CPU占用率相同。

要让CPU的占用率,呈函数 y = calc(t) (0 <= y <= 1, t为时间,单位为ms )分布,只要取间隔很短的一系列点,认为在某个间隔内,y值近似不变。

设间隔值为GAP,显然在指定t值附近的GAP这段时间内,

CPU占用时间为:busy = GAP * calc(t),

CPU空闲时间为:idle = GAP – busy

因此,很容易写出下面这个通用函数:

void solve(Func *calc)
{
double tb = 0;
while(1) {
unsigned ta = get_time();
double r = calc(tb);
if (r < 0 || r > 1) r = 1;
DWORD busy = r * GAP;
while(get_time() - ta < busy) {}
Sleep(GAP - busy);
tb += GAP;
}
}

如果CPU占用率曲线不是周期性变化,就要对每个t值都要计算一次,否则,可以只计算第一个周期内的各个t值,其它周期的直接取缓存计算结果。

以CPU占用率为正弦曲线为例,显然:y = 0.5 * (1 + sin(a * t + b))

其周期T = 2 * PI / a (PI = 3.1415927),可以指定T值为60s即60000ms,则

可以确定a值为 2 * PI / T, 若在这60000ms内我们计算200次(c = 200),则GAP值为 T / c = 300ms.也就是说,只要确定了周期和计算次数,其它几个参数也都确定下来。

完整代码如下:

#include<windows.h>
#include<cstdio>
#include<cmath>

constint PERIOD = 60 * 1000; //60,000 ms
constint COUNT = 200;

constdouble PI = 3.1415926535898;
constdouble GAP = (double)PERIOD / COUNT;
constdouble FACTOR = 2 * PI / PERIOD;

typedefdouble Func(double);
inline DWORD get_time() { return GetTickCount(); }

double calc2(double x) { return (1 + sin(FACTOR * x)) / 2;}

double calc3(double)
{
static double cache[COUNT];
static int count = 0;
static bool first =true;
if (first) {
double x = 0.0;
for (int i = 0; i < COUNT; ++i, x += GAP)
cache[i] = (1.0 + sin(FACTOR * x)) / 2.0;
first =false;
}
if (count >= COUNT) count = 0;
return cache[count++];
}

double calc4(double) { return 0.8;}

void solve(Func *calc)
{
double tb = 0;
while(1) {
unsigned ta = get_time();
double r = calc(tb);
if (r < 0 || r > 1) r = 1;
DWORD busy = r * GAP;
while(get_time() - ta < busy) {}
Sleep(GAP - busy);
tb += GAP;
}
}


void run()
{
Func *func[] = { calc2, calc3, calc4 };
Func *calc = func[1];
const int MAX_CPUS = 32;
HANDLE handle[MAX_CPUS];
DWORD thread_id[MAX_CPUS];
SYSTEM_INFO info;
GetSystemInfo(&info);
const int num = info.dwNumberOfProcessors;
for (int i = 0; i < num; ++i){
if ( (handle[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)solve,
(VOID*)calc, 0, &thread_id[i])) != NULL)
SetThreadAffinityMask(handle[i], i + 1);
}
WaitForSingleObject(handle[0],INFINITE);
}


int main()
{
run();
}

稍微优化下:

#include<cstdio>
#include<cmath>
#include<windows.h>

constint PERIOD = 60 * 1000; //60,000 ms
constint COUNT = 300;

constdouble GAP_LINEAR = 100;

constdouble PI = 3.1415926535898;
constdouble GAP = (double)PERIOD / COUNT;
constdouble FACTOR = 2 * PI / PERIOD;


typedefdouble Func(double);
inline DWORD get_time() { return GetTickCount(); }

double calc_sin(double x) { return (1 + sin(FACTOR * x)) / 2;}

staticdouble Ratio = 0.7;

void set_ratio()
{
double ret = 0.0;
printf("Ratio:([0,1]) ");
scanf("%lf", &ret);
if (ret < 0.0 || ret > 1.0) ret = 0.5;
Ratio = ret;
}

void solve_nonperiod(Func *calc)
{
double tb = 0;
while(1) {
unsigned ta = get_time();
double r = calc(tb);
if (r < 0 || r > 1) r = 1;
DWORD busy = r * GAP;
while(get_time() - ta < busy) {}
Sleep(GAP - busy);
//tb += GAP;
tb += get_time() - ta;
}
}

void solve_period(Func *calc)
{
double x = 0.0;
double cache[COUNT];
for (int i = 0; i < COUNT; ++i, x += GAP)
cache[i] = calc(x);
int count = 0;
while(1) {
unsigned ta = get_time();
if (count >= COUNT) count = 0;
double r = cache[count++];
DWORD busy = r * GAP;
while(get_time() - ta < busy) {}
Sleep(GAP - busy);
}
}

void solve_linear(Func*)
{
const unsigned BUSY = Ratio * GAP_LINEAR;
const unsigned IDLE = (1 - Ratio) * GAP_LINEAR;
while(1) {
unsigned ta = get_time();
while(get_time() - ta < BUSY) {}
Sleep(IDLE);
}
}


void run(unsigned index = 0,double ratio = -1.0)
{
typedefvoid Solve(Func *calc);
Func *func[] = { calc_sin};
Func *calc = func[0];
Solve *solve_func[] = { solve_linear, solve_period, solve_nonperiod };
if (index >= sizeof(solve_func) / sizeof(solve_func[0])) index = 0;
Solve *solve = solve_func[index];
if (solve == solve_linear) {
if (ratio >= 0 && ratio <= 1) Ratio = ratio;
else set_ratio();
}
const int MAX_CPUS = 32;
HANDLE handle[MAX_CPUS];
DWORD thread_id[MAX_CPUS];
SYSTEM_INFO info;
GetSystemInfo(&info);
const int num = info.dwNumberOfProcessors;
for (int i = 0; i < num; ++i){
if ((handle[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)solve,
(VOID*)calc, 0, &thread_id[i])) != NULL)
SetThreadAffinityMask(handle[i], i + 1);
}
WaitForSingleObject(handle[0],INFINITE);
}


int main()
{
run(0, 0.5);
//run(0);
//run(1);
//run(1);
}

转载于:https://www.cnblogs.com/owl-home/archive/2013/04/16/3025159.html

【自定义CPU占用率】相关推荐

  1. window服务器cpu过高的排查_线上服务器发生CPU占用率过高应该如何排查并定位问题?...

    国外开发者平台 HankerRank 发布的 2018 年开发者技能调查报告中有一项关于"雇主最看重哪些核心能力"的调查,结果显示如下: 排名前几的比较受重视的能力分别为:解决问题 ...

  2. 原创|面试官:线上服务器CPU占用率高如何排查定位问题?

    国外开发者平台 HankerRank 发布的 2018 年开发者技能调查报告中有一项关于"雇主最看重哪些核心能力"的调查,结果显示如下: 排名前几的比较受重视的能力分别为:解决问题 ...

  3. 服务器cpu占用率高怎么解决,线上服务器CPU占用率高怎么办?

    如果线上服务器发生CPU占用率高时,应该如何排查并定位问题. 1.问题发现 本文整理自一个真实的案例,是楼主负责的业务,在一次大促之前的压测时发现了这个问题. 在每次大促之前,我们的测试人员都会对网站 ...

  4. 服务器定位cpu高占用率代码php,面试官:线上服务器CPU占用率高如何排查定位问题?,...

    面试官:线上服务器CPU占用率高如何排查定位问题?, 国外开发者平台 HankerRank 发布的 2018 年开发者技能调查报告中有一项关于"雇主最看重哪些核心能力"的调查,结果 ...

  5. 面试官:线上服务器CPU占用率高如何排查定位问题?

    开发十年,就只剩下这套架构体系了!! 国外开发者平台 HankerRank 发布的 2018 年开发者技能调查报告中有一项关于"雇主最看重哪些核心能力"的调查,结果显示如下:  ...

  6. 线上服务器CPU占用率高如何排查定位问题?

    (关联着看看这篇文章:https://blog.csdn.net/u011277123/article/details/103768939) 解决问题的能力以超高比例排名第一,这也是为什么很多面试过程 ...

  7. IDEA的CPU占用率高问题解决方法

    前言:这段时间发现 IDEA 的 CPU 占用率猛涨,时不时就飙升到百分之7.80,使得敲代码的体验感十分不佳,在经过一番查找之后终于解决了问题,在此记录一下 IDEA的CPU占用率高问题解决方法 问 ...

  8. Linux 下杀毒软件 CPU 占用率为何持续升高?

    作者 | beyondma  责编 | 张文 来源 | CSDN 博客 头图 | CSDN 下载自视觉中国 最近笔者遇到这样一个相对比较疑难的事件,某个在 Linux 下运行的杀毒软件启动后,在某些情 ...

  9. CPU占用率高的九种可能~

    首先是考虑病毒~ 其次: 1.防杀毒软件造成故障 由于新版的KV.金山.瑞星都加入了对网页.插件.邮件的随机监控,无疑增大了系统负担.处理方式:基本上没有合理的处理方式,尽量使用最少的监控服务吧,或者 ...

最新文章

  1. 一招修复内存不能read_read文件一个字节实际会发生多大的磁盘IO?
  2. android 新闻编辑,超机访问:ZOL手机新闻编辑背后的故事
  3. 【Python】Flask框架系列(二):安装、配置文件、增删改查
  4. 学霸情侣一起投身国防事业,爱情和优秀同时发生了…
  5. EMLO模板GeMedia媒体范儿[小梦修改尊享版]
  6. Java之品优购课程讲义_day16(2)
  7. 困计算机无法启动adb,win7系统无法启动adb.exe工具包的解决方法
  8. IE、firefox下怎样获得自定义属性的值
  9. html5中的web worker用法
  10. 【大数据实验2】hadoop配置、测试和实例
  11. 电商推荐系统论文:基于Spark机器学习的电商推荐系统的设计与实现,大数据电商推荐系统毕设论文,Spring MLlib电商推荐系统
  12. MAC表和ARP表的老化时间:
  13. 2019年我能变强组队训练赛第十场 C Criss-Cross Cables(优先队列模拟)
  14. kali linux安全牛教程,Kali Linux渗透测试(安全牛)最新完整版教程160G
  15. 什么是瀑布图_什么是瀑布图以及为什么我需要一个
  16. 浅谈stm32的低功耗模式
  17. Android app开发:代码切换移动数据走SIM1/SIM2
  18. 武汉计算机学校分数线,武汉交通学校2021年招生录取分数线
  19. 双下划线一粗一细怎么加_为什么下划线粗细不一样
  20. 3.23早间BTC/ETH急剧回踩,短暂拉升等机会

热门文章

  1. 后台如何实现对APP版本更新管理?
  2. 【老生谈算法】matlab实现三相短路电流计算源码——短路电流
  3. CGSS2015问卷数据STATA重编码命令(部分)
  4. 分享下这些软件外包公司(2023最新版),程序员有福了
  5. LPL2019职业联赛春季+夏季赛数据分析
  6. 船舶导航软件测试,船舶导航系统
  7. 简答题软件测试的过程是什么,软件测试简答题库
  8. Sitecore DMS 中自定义Rule 实现页面个性化
  9. 安卓解决输入的时候 背景下滑问题
  10. UTF-8编码方式汉字和英文各占据的字节数