任务难度:3星
任务说明:
写一个程序,让用户来决定Windows任务管理器(Task Manager)的CPU占用率。程序越精简越好,计算机语言不限。例如,可以实现下面三种情况:
1.CPU占用率固定50%,为一条直线
2.CPU占用率为一条直线,具体占用率由命令行决定(参数范围1~100)
3.CPU占用率状态为一条正弦曲线
我们先要解决几个最基本的问题,如何查看CPU的占用率?CPU占用率的定义?程序和CPU占用率的关系?
在任务管理器-cpu-资源监视器里可以查看CPU的占用率(cpu usage)
先回想一下操作系统课上,对CPU占用率的定义,CPU占用率为:进程使用CPU时间/(CPU空闲时间+CPU使用时间)
接下来,让我们先简化问题
先考虑在单核的电脑情况下如何让CPU的占用率达到100%?
根据定义,我们要让CPU处于全负荷状态下,也就是进程始终占用着CPU,那么一个进程什么时候会闲下来不去占用CPU呢?那就是当它运行结束或等待事件方式或进入休眠状态,要让一个进程始终不闲下来会是什么情况呢? 对,那就是死循环!
于是我们可以写一段死循环的程序,运行,并查看资源监视器中的CPU利用率,我在我自己的电脑上查看,发现CPU利用率会逐渐稳定到25%?想一想这是为什么?顺带一提,我的电脑是四核处理器。
明白这一点后,我们如何让CPU占用率达到一半呢?是不是让CPU在任务管理器刷新时间内一般时间闲一半时间闲?
忙起来我们只需要进行循环空转即可,那么要如何让CPU闲下来呢?之前我们提到过让进程进入休眠状态即可,这里我们利用Sleep函数(包含在c语言的windows.h头文件)即可,如何控制忙闲的时间呢?我们利用GetTickCount()函数不断返回当前时间即可,代码如下:
#include <windows.h>
#include <stdlib.h>
DWORD busyTime=10;
DWORD idleTime=busyTime;
DWORD startTime=0;
int main()
{
while(true)
{
startTime=GetTickCount();
while((GetTickCount()-startTime)<=busyTime)
;//循环空转的时间为busyTime
//空闲的时间为idleTime
Sleep(idleTime);
}
return 0;
}
当idleTime=busyTime时 CPU占用率在单核情况下是50%,而其他情况只需要修改这两个变量的比例即可。
接下来再给出CPU曲线成正弦曲线的代码(原理同上,只是将每一个时间间隔忙闲时间的比例不断变化而已)
#include <math.h>
#include <cstdio>
#include <windows.h>
#include <stdlib.h>
//正弦曲线
const double SPLIT=0.01;
const int COUNT=200; //存储两百个时间间隔点
const double PI=3.141592653;
const int INTERVAL=300;
DWORD busySPAN[COUNT]; //每一个点应该忙的时间
DWORD idleSPAN[COUNT]; //每一个点应该闲的时间
int main()
{
/*初始化busySPAN[]和idleSPAN[]*/
int half=INTERVAL/2;
double Radian=0.0;
for (int i=0;i<COUNT;i++)
{
busySPAN[i]=(DWORD)(half+(sin(PI*Radian)*half));
idleSPAN[i]=(DWORD)(INTERVAL-busySPAN[i]);
Radian+=SPLIT;
}
/*不断循环和修改两个数组的下标,让CPU占用率呈现正弦曲线*/
DWORD startTime=0;
int j=0;
while(true)
{
j%=COUNT;
startTime=GetTickCount();
while(GetTickCount()-startTime<=busySPAN[j])
;
Sleep(idleSPAN[j]);
j++;
}
return 0;
}