任务难度: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;
}