Windows控制CPU使用率曲线

    技术2022-05-19  23

        前几天无聊,按照《编程之美》第一题写了个控制CPU使用率的程序。本以为没什么,可是今天早上在ChinaUnix上看到完全复制书上的代码毫无原创的帖子居然很火。。。所以把自己的代码贴出来,供以后学习……

        效果图如下:

     

        其实程序的设计思想很简单,Windows任务管理器中CPU使用率基本上1s刷新一次,而CPU使用率其实就是在1s中CPU忙和闲时间的均值。因此,根据我们想要得到的CPU曲线的特点,我们首先做出忙闲时间的表,CPU根据忙闲时间选择执行或挂起。

    代码如下:

     #include <windows.h> #include <stdlib.h> #include <math.h> #define COUNT 200 const double SPLIT = 0.01; const double PI = 3.14159265; const double SLOPE = 150; const int INTERVAL = 300; DWORD WINAPI SineThread(LPVOID Sine) { DWORD busySpan[COUNT]; DWORD idleSpan[COUNT]; int half = INTERVAL/2; double radian = 0.0; DWORD startTime; int i; for (i=0; i<COUNT; i++) { busySpan[i] = (DWORD)(half + half*sin(PI*radian)); idleSpan[i] = (DWORD)(INTERVAL - busySpan[i]); radian += SPLIT; } i = 0; while(1) { i %= COUNT; startTime = GetTickCount(); while((GetTickCount()-startTime) <= busySpan[i]) ; Sleep(idleSpan[i]); i++; } return 0; } DWORD WINAPI SawThread(LPVOID Saw) { DWORD busySpan[COUNT]; DWORD idleSpan[COUNT]; int half = INTERVAL/2; double radian = 0.0; DWORD startTime; int i; for (i=0; i<COUNT; i++) { busySpan[i] = (DWORD)(SLOPE*radian); idleSpan[i] = (DWORD)(INTERVAL - busySpan[i]); radian += SPLIT; } i = 0; while(1) { i %= COUNT; startTime = GetTickCount(); while((GetTickCount()-startTime) <= busySpan[i]) ; Sleep(idleSpan[i]); i++; } return 0; } int main() { HANDLE hThread1, hThread2; DWORD dwThreadId1, dwThreadId2; hThread1 = CreateThread(NULL, 0, SineThread, 0, CREATE_SUSPENDED, &dwThreadId1); hThread2 = CreateThread(NULL, 0, SawThread, 0, CREATE_SUSPENDED, &dwThreadId2); SetThreadAffinityMask(hThread1, 1); SetThreadAffinityMask(hThread2, 2); ResumeThread(hThread1); ResumeThread(hThread2); SuspendThread(GetCurrentThread()); return 0; }

        其中INTERVAL可以视为周期,而COUNT和SPLIT分别为采样点数和步长,SLOPE就是斜率了。。。另外,对于双核而言,编程之美上的代码并不完美,于是按照书上的指点,使用SetThreadAffinityMask()将两个线程分别在每个核去执行。

    Linux下代码完全仿照Windows写出,知识获取时间的函数不同,另外,使用usleep实现微秒级定时: #include <unistd.h> #include <stdlib.h> #include <math.h> #include <time.h> #include <sys/time.h> #define COUNT 200 #define SPLIT 0.01 #define PI 3.14159265 #define INTERVAL 100 double get_time() { struct timeval tv; gettimeofday(&tv, NULL); return (tv.tv_sec*1000+tv.tv_usec*1.0/1000); /* ms */ } int main() { double busy_span[COUNT]; /* need to modify */ double idle_span[COUNT]; int half = INTERVAL/2; double radian = 0.0; double start_time; int i; for(i=0; i<COUNT; i++) { busy_span[i] = (double)(half + half*sin(PI*radian)); idle_span[i] = (double)(INTERVAL - busy_span[i]); radian += SPLIT; } i = 0; while(1) { i %= COUNT; start_time = get_time(); while((get_time()-start_time) <= busy_span[i]) ; usleep(idle_span[i]*1000); i++; } return 0; }


    最新回复(0)