有趣的编程----控制自己电脑的CPU
2013-11-13 11:08
169 查看
一、题目:写一个程序,让windows任务管理器中的CPU占用率显示为一条正弦函数曲线。
第一眼看到这个题目,本人确实是没有多大思路的。因为一直没有对性能和CPU占用上考虑太多。真正看书查资料弄完才觉得确实很不错的一个应用题。以下将一步步完成控制的任务。二、本人运行环境:
操作系统:win 7 32位CPU: intel i7 2630QM(2.0GHZ 4核8线程)
三、具体实现
1. 多CPU的解决办法
因为程序在多CPU下会效果显示混乱,所以需要代码来指定程序在哪个CPU下运行。可以用Windows API来指定CPU,代码如下:
[cpp]
view plaincopyprint?
//让进程在指定处理器上运行(在第一个CPU上运行, 对多CPU的处理) SetProcessAffinityMask( GetCurrentProcess(), 0x00000001 //cpu mask );
//让进程在指定处理器上运行(在第一个CPU上运行, 对多CPU的处理) SetProcessAffinityMask( GetCurrentProcess(), 0x00000001 //cpu mask );
2. 控制CPU的思路
CPU有两种状态:忙、闲。控制忙:死循环。
控制闲:睡眠。
Windows资源管理器:显示的CPU曲线是一条记录型的曲线,会记录CPU的当前的占用率,然后慢慢绘制成线。
3. 通过计算CPU频率来控制CPU
[cpp]view plaincopyprint?
#include <stdio.h>
#include <stdlib.h>
#include "windows.h"
//控制CPU , 需要计算CPU运行时间
int main()
{
//让进程在指定处理器上运行(在第一个CPU上运行, 对多CPU的处理) SetProcessAffinityMask( GetCurrentProcess(), 0x00000001 //cpu mask );
for(;;)
{
//CPU 2.0GHZ 4核心 8线程
//计算方法: 2.0*10的9次方 , 现代CPU每个时钟周期可以执行2条以上的代码
//2000 000 000*2/5=800 000 000 平均
for(int i=0;i<8000000;i++)
;
Sleep(10);//10ms比较接近windows的调度时间片
}
//system("PAUSE");
return 0;
}
#include <stdio.h>运行效果:
#include <stdlib.h>
#include "windows.h"
//控制CPU , 需要计算CPU运行时间
int main()
{
//让进程在指定处理器上运行(在第一个CPU上运行, 对多CPU的处理) SetProcessAffinityMask( GetCurrentProcess(), 0x00000001 //cpu mask );
for(;;)
{
//CPU 2.0GHZ 4核心 8线程
//计算方法: 2.0*10的9次方 , 现代CPU每个时钟周期可以执行2条以上的代码
//2000 000 000*2/5=800 000 000 平均
for(int i=0;i<8000000;i++)
;
Sleep(10);//10ms比较接近windows的调度时间片
}
//system("PAUSE");
return 0;
}
可以看出,效果不是很好。人工计算肯定是不准确的!而且其他程序也会占用CPU。
4. 通过GetTickCount()函数来设置时间间隔
这样做的好处就是不用估算CPU的频率了,较上面的方法肯定好多了。[cpp]
view plaincopyprint?
#include <stdio.h>
#include <stdlib.h>
#include "windows.h"
//控制CPU
int main()
{
//让进程在指定处理器上运行(在第一个CPU上运行, 对多CPU的处理) SetProcessAffinityMask( GetCurrentProcess(), 0x00000001 //cpu mask );
int busyTime = 100;
int idleTime = busyTime;
int start = 0;
while(true)
{
//用系统函数省去了CPU运行时间的估算
start = GetTickCount();
while((GetTickCount() - start) <= busyTime)
;
//空闲
Sleep(idleTime);
}
//system("PAUSE");
return 0;
}
#include <stdio.h>效果:
#include <stdlib.h>
#include "windows.h"
//控制CPU
int main()
{
//让进程在指定处理器上运行(在第一个CPU上运行, 对多CPU的处理) SetProcessAffinityMask( GetCurrentProcess(), 0x00000001 //cpu mask );
int busyTime = 100;
int idleTime = busyTime;
int start = 0;
while(true)
{
//用系统函数省去了CPU运行时间的估算
start = GetTickCount();
while((GetTickCount() - start) <= busyTime)
;
//空闲
Sleep(idleTime);
}
//system("PAUSE");
return 0;
}
当然效果也一般,为下面的做铺垫。
5. 画正弦函数
要想画出正弦函数曲线,CPU忙的时间必须是慢慢递增的,然后递减。而CPU闲的时间必须是慢慢递减然后递增。这样就是一个周期。最后一直循环重复即得到正弦函数曲线。
一下打印出部分忙闲时间关系:
代码:
[cpp]
view plaincopyprint?
#include <Windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <tchar.h>
const double SPLIT = 0.01;
const int COUNT = 200;
const double PI = 3.14159265;
const int INTERVAL = 300; //间隔时间
//画出一条正弦曲线
int _tmain(int argc, _TCHAR* argv[])
{
//让进程在指定处理器上运行(在第一个CPU上运行, 对多CPU的处理) SetProcessAffinityMask( GetCurrentProcess(), 0x00000001 //cpu mask );
//1. 设置忙与闲时的时间数组
DWORD busySpan[COUNT]; //array of busy times
DWORD idleSpan[COUNT]; //array of idle times
int half = INTERVAL / 2;
double radian = 0.0; //弧度
for(int i = 0; i < COUNT; i++)
{
//sin(x)的取值范围是[-1,1],为了完整显示,必须给它作些参数调整
busySpan[i] = (DWORD)(half + (sin(PI * radian) * half));
idleSpan[i] = INTERVAL - busySpan[i];
radian += SPLIT; //每次增一点点
}
//测试:输出忙与闲时的时间数组, 写入文件result.txt
FILE *fp;
fp = fopen("result.txt", "a+"); //a+表示追加方式
for(int i = 0; i < COUNT; i++)
{
//printf("busySpan[%d] is %d\n",i,busySpan[i]);
//printf("idleSpan[%d] is %d\n\n",i,idleSpan[i]);
fprintf(fp, "busySpan[%d] is %d\n" , i, busySpan[i]);
fprintf(fp, "idleSpan[%d] is %d\n\n" , i , idleSpan[i]);
}
fclose(fp);
//2. 画曲线
DWORD startTime = 0;
int j = 0;
while (true)
{
j = j % COUNT; //COUNT次为一个周期
startTime = GetTickCount();
while ((GetTickCount() - startTime) <= busySpan[j])
;
Sleep(idleSpan[j]);
j++;
}
return 0;
}
#include <Windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <tchar.h>
const double SPLIT = 0.01;
const int COUNT = 200;
const double PI = 3.14159265;
const int INTERVAL = 300; //间隔时间
//画出一条正弦曲线
int _tmain(int argc, _TCHAR* argv[])
{
//让进程在指定处理器上运行(在第一个CPU上运行, 对多CPU的处理) SetProcessAffinityMask( GetCurrentProcess(), 0x00000001 //cpu mask );
//1. 设置忙与闲时的时间数组
DWORD busySpan[COUNT]; //array of busy times
DWORD idleSpan[COUNT]; //array of idle times
int half = INTERVAL / 2;
double radian = 0.0; //弧度
for(int i = 0; i < COUNT; i++)
{
//sin(x)的取值范围是[-1,1],为了完整显示,必须给它作些参数调整
busySpan[i] = (DWORD)(half + (sin(PI * radian) * half));
idleSpan[i] = INTERVAL - busySpan[i];
radian += SPLIT; //每次增一点点
}
//测试:输出忙与闲时的时间数组, 写入文件result.txt
FILE *fp;
fp = fopen("result.txt", "a+"); //a+表示追加方式
for(int i = 0; i < COUNT; i++)
{
//printf("busySpan[%d] is %d\n",i,busySpan[i]);
//printf("idleSpan[%d] is %d\n\n",i,idleSpan[i]);
fprintf(fp, "busySpan[%d] is %d\n" , i, busySpan[i]);
fprintf(fp, "idleSpan[%d] is %d\n\n" , i , idleSpan[i]);
}
fclose(fp);
//2. 画曲线
DWORD startTime = 0;
int j = 0;
while (true)
{
j = j % COUNT; //COUNT次为一个周期
startTime = GetTickCount();
while ((GetTickCount() - startTime) <= busySpan[j])
;
Sleep(idleSpan[j]);
j++;
}
return 0;
}
运行效果:
改变间隔时间INTERVAL = 100; 时可以相应使周期减小:
转载请注明出处:http://blog.csdn.net/xn4545945
参考《编程之美》与 互联网
相关文章推荐
- 有趣的编程----控制自己电脑的CPU
- 有趣的编程----控制自己电脑的CPU
- 有趣的编程----控制自己电脑的CPU
- 运行控制[置顶] 有趣的编程----控制自己电脑的CPU
- 技术三等奖:有趣的编程:控制自己电脑的CPU【评委点评】
- win10如何查看自己电脑有几个CPU,每个CPU有多少个核心数
- 怎么查看自己电脑CPU是多少位
- 你能控制自己坐在电脑前的时间吗?
- Socket编程,自己电脑做服务端和客户端
- 只需java编程,就可实现工业自动化控制的Android工业平板电脑开发
- 如何查看自己电脑的CPU是几核
- 在c#编程中自己控制XML的创建和读取
- 如何查看自己电脑的CPU是几核
- 怎么查看自己电脑CPU是多少位的
- 最近戴着眼镜坐电脑前总是不自觉的眼痛就搜了下怎么保护眼睛无意中看到了这篇文章希望广大爱好编程的朋友多注意保护自己的眼睛!!
- second blog编程之美------控制cpu曲线
- 编程之美,JAVA控制CPU的使用率(2),完美曲线
- 在办公室控制自己家电脑的方法
- UBOOT命令怎么自己添加 嵌入式汇编控制cpu CACH
- 编程之美-JAVA控制CPU的使用率(一)