让CPU占用率曲线听你指挥

让CPU占用率曲线听你指挥(zt) 问题写一个程序,让用户来决定Windows任务管理器(Task Manager)的CPU占用率。程序越精简越好,计算机语言不限。例如,可以实现下面三种情况:1. CPU的占用率固定在50%,为一条直线;2. CPU的占用率为一条直线,但是具体占用率由命令行参数决定(参数范围1~ 100);3. CPU的占用率状态是一个正弦曲线。分析与解法有一名学生写了如下的代码:while ( 阅读详情

由于网上已经有很多有关此问题的博客,本文参考了http://blog.youkuaiyun.com/wesweeky/article/details/6402564

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

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

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

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

控制的方式其实就是在任务管理器刷新的一个周期内,使得cpu忙的时间控制在一定的比例。

任务管理器的刷新周期是1秒,我的cpu是2.4GHZ,

现代cpu每个时钟周期可执行两条以上的代码,取平均值2,于是

(2400 000 000*2)/5=960000000(循环/秒) 每秒可以执行循环960000000次

不能简单的取n=9600000000然后sleep(1000),如果让cpu工作1s,休息1s很可能是锯齿,先达到一个峰值然后跌入一个很低的占有率;所以我们睡眠时间改为10ms,10ms比较接近windows的调度时间,n=9600000。如果sleep时间选的太小,会造成线程频繁的唤醒和挂起,无形中增加了内核时间的不确定性因此代码如下:

一、单核情况下

    解法一:

  1. #include <windows.h>  
  2.   
  3. int main(void)  
  4. {  
  5.     //50%  
  6.     //Thread 0 can only run on CPU 0.  
  7.     //SetThreadAffinityMask(GetCurrentProcess(), 0x00000001);  //这个是指定在哪个cpu上运行该线程
  8.     while(true)  
  9.     {  
  10.         for(int i=0;i<10120000;i++)  
  11.             ;  
  12.         Sleep(10);  
  13.     }  
  14.     return 0;  
  15.       
  16.   
  17. }  

                 注意:不同型号的机器的差异性,使得该方法有很大的缺陷,比如我的电脑,只能在调节Sleep(30)的时候才能达到勉强的效果如图:

                  

解法二:

解法二:使用GetTickCount()和Sleep()

GetTickCount()可以得到“系统启动到现在”所经历的时间的毫秒值,最多可以统计49.7天,因此我们可以利用GetTickCount()判断busy loop要循环多久,如下:

[cpp]  view plain copy
  1. #include <windows.h>  
  2.   
  3. int main(void)  
  4. {  
  5.           
  6.     //50%  
  7.     int busyTime=10;  
  8.     int idleTime=busyTime;  
  9.     _int64 startTime;  
  10.          //SetThreadAffinityMask(GetCurrentProcess(), 0x00000001);  
  11.     while(true)  
  12.     {  
  13.         startTime=GetTickCount();  
  14.         while((GetTickCount()-startTime)<=busyTime)  
  15.         {  
  16.             ;  
  17.         }  
  18.         Sleep(idleTime);  
  19.     }  
  20.     return 0;  
  21. }  

            注意:该方法有和方法一有同样的缺点,我的机器的busyTime=50,效果如图:

      



上面两种解法都是假设当前系统只有当前程序在运行,但实际上,操作系统有很多程序会同时调试执行各种任务,如果此刻进程使用10%的cpu,那我们的程序只有使用40%的cpu才能达到50%的效果。

Perfmon.exe是从WIN NT开始就包含在windows管理工具中的专业检测工具之一。我们可以用程序来查询Perfmon的值,.Net Framework提供了PerformanceCounter这一对象,可以方便的查询当前各种性能数据,包括cpu使用率,因此解法三如下:

      

解法三:能动态适应的解法

 

[c-sharp]  view plain copy
  1. using System;  
  2. using System.Diagnostics;  
  3. namespace cpu  
  4. {  
  5.     class Program  
  6.     {  
  7.         static void Main(string[] args)  
  8.         {  
  9.            cpu(0.5);  
  10.         }  
  11.         static void cpu(double level)  
  12.         {  
  13.             PerformanceCounter p = new PerformanceCounter("Processor", "% Processor Time", "_Total");  
  14.             if (p == null)  
  15.             {  
  16.                 return;  
  17.             }  
  18.             while (true)  
  19.             {  
  20.                 if (p.NextValue() > level)  
  21.                     System.Threading.Thread.Sleep(10);  
  22.             }  
  23.         }  
  24.     }  
  25. }  

由于我的实验都是在虚拟机上安装的Qt开发环境的,没有安装VS,所以无法实验该C#代码的实现。

    

解法四:正弦曲线

[cpp]  view plain copy
  1. #include <windows.h>  
  2. #include <math.h>  
  3. int main(void)  
  4. {  
  5.          SetThreadAffinityMask(GetCurrentProcess(), 0x00000001);  
  6.     const double SPLIT=0.01;  
  7.     const int COUNT=200;  
  8.     const double PI=3.14159265;  
  9.     const int INTERVAL=300;  
  10.     DWORD busySpan[COUNT]; //array of busy time  
  11.     DWORD idleSpan[COUNT]; //array of idle time  
  12.     int half=INTERVAL/2;  
  13.     double radian=0.0;  
  14.     for(int i=0;i<COUNT;i++)  
  15.     {  
  16.         busySpan[i]=(DWORD)(half+(sin(PI*radian)*half));  
  17.         idleSpan[i]=INTERVAL-busySpan[i];  
  18.         radian+=SPLIT;  
  19.     }  
  20.     DWORD startTime=0;  
  21.     int j=0;  
  22.     while(true)  
  23.     {  
  24.         j=j%COUNT;  
  25.         startTime=GetTickCount();  
  26.         while((GetTickCount()-startTime)<=busySpan[j])  
  27.             ;  
  28.         Sleep(idleSpan[j]);  
  29.         j++;  
  30.     }  
  31.     return 0;  
  32. }  

其中busySpan[i]=(DWORD)(half+(sin(PI*radian)*half));
  idleSpan[i]=INTERVAL-busySpan[i];

这样保证了占有率=busy/(busy+idle)=(half+(sin(PI*radian)*half))/(2*half)=(1+sin(PI*radian))/2 在0到100%之间!。

               

下面更深入讨论,http://www.cnblogs.com/flyinghearts/archive/2011/03/22/1991965.html这篇博文很好,讨论了在双核情况下,每个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

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

[cpp]  view plain copy
  1. void solve(Func *calc)  
  2. {  
  3.   double tb = 0;  
  4.   while(1)   
  5.  {  
  6.     unsigned ta = get_time();  
  7.     double r = calc(tb);  
  8.     if (r < 0 || r > 1) r = 1;  
  9.     DWORD busy = r * GAP;  
  10.     while(get_time() - ta < busy) {}  
  11.     Sleep(GAP - busy);  
  12.     tb += GAP;  
  13.   }  
  14. }  

 

如果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.也就是说,只要确定了周期和计算次数,其它几个参数也都确定下来。

代码如下

[cpp]  view plain copy
  1. #include<iostream>  
  2. #include<cmath>  
  3. #include<windows.h>  
  4.   
  5. static int PERIOD = 60 * 1000; //周期ms  
  6. const int COUNT = 300;  //一个周期计算次数  
  7. const double GAP_LINEAR = 100;  //线性函数时间间隔100ms  
  8. const double PI = 3.1415926535898; //PI  
  9. const double GAP = (double)PERIOD / COUNT; //周期函数时间间隔  
  10. const double FACTOR = 2 * PI / PERIOD;  //周期函数的系数  
  11. static double Ratio = 0.5;  //线性函数的值 0.5即50%  
  12. static double Max=0.9; //方波函数的最大值  
  13. static double Min=0.1; //方波函数的最小值  
  14.   
  15. typedef double Func(double);  //定义一个函数类型 Func*为函数指针  
  16. typedef void Solve(Func *calc);//定义函数类型,参数为函数指针Func*  
  17. inline DWORD get_time()   
  18. {   
  19.     return GetTickCount(); //操作系统启动到现在所经过的时间ms  
  20. }  
  21. double calc_sin(double x)  //调用周期函数solve_period的参数  
  22. {    
  23.     return (1 + sin(FACTOR * x)) / 2; //y=1/2(1+sin(a*x))  
  24. }  
  25. double calc_fangbo(double x)  //调用周期函数solve_period的参数  
  26. {  
  27.     //方波函数  
  28.     if(x<=PERIOD/2) return Max;  
  29.     else return Min;  
  30. }  
  31.   
  32. void solve_period(Func *calc) //线程函数为周期函数  
  33. {  
  34.     double x = 0.0;  
  35.     double cache[COUNT];  
  36.     for (int i = 0; i < COUNT; ++i, x += GAP)   
  37.         cache[i] = calc(x);   
  38.     int count = 0;  
  39.     while(1)  
  40.     {  
  41.         unsigned ta = get_time();  
  42.         if (count >= COUNT) count = 0;  
  43.         double r = cache[count++];  
  44.         DWORD busy = r * GAP;  
  45.         while(get_time() - ta < busy) {}  
  46.         Sleep(GAP - busy);  
  47.   }  
  48. }  
  49.   
  50. void solve_linear(Func*)  //线程函数为线性函数,参数为空 NULL  
  51. {  
  52.     const unsigned BUSY =  Ratio * GAP_LINEAR;  
  53.     const unsigned IDLE = (1 - Ratio) * GAP_LINEAR;  
  54.     while(1)  
  55.     {  
  56.         unsigned ta = get_time();  
  57.         while(get_time() - ta < BUSY) {}  
  58.         Sleep(IDLE);  
  59.     }  
  60. }  
  61. //void solve_nonperiod(Func *calc) //非周期函数的处理,暂没实验  
  62. //{  
  63. //  double tb = 0;  
  64. //  while(1)  
  65. //  {  
  66. //    unsigned ta = get_time();  
  67. //    double r = calc(tb);  
  68. //    if (r < 0 || r > 1) r = 1;  
  69. //    DWORD busy = r * GAP;  
  70. //    while(get_time() - ta < busy) {}  
  71. //    Sleep(GAP - busy);  
  72. //    //tb += GAP;  
  73. //    tb += get_time() - ta;  
  74. //  }  
  75. //}  
  76.   
  77. void run(int i=1,double R=0.5,double T=60000,double max=0.9,double min=0.1)  
  78.      //i为输出状态,R为直线函数的值,T为周期函数的周期,max方波最大值,min方波最小值  
  79. {  
  80.     Ratio=R; PERIOD=T; Max=max; Min=min;  
  81.     Func *func[] = {NULL ,calc_sin,calc_fangbo};  //传给Solve的参数,函数指针数组  
  82.     Solve *solve_func[] = { solve_linear, solve_period};  //Solve函数指针数组  
  83.     const int NUM_CPUS = 2;  //双核,通用的可以用下面GetSystemInfo得到cpu数目  
  84.     HANDLE handle[NUM_CPUS];    
  85.     DWORD thread_id[NUM_CPUS]; //线程id  
  86.     //SYSTEM_INFO info;  
  87.     //GetSystemInfo(&info);   //得到cpu数目  
  88.     //const int num = info.dwNumberOfProcessors;  
  89.     switch(i)  
  90.     {  
  91.     case 1: //cpu1 ,cpu2都输出直线  
  92.         {  
  93.             for (int i = 0; i < NUM_CPUS; ++i)  
  94.             {  
  95.                 Func *calc = func[0];  
  96.                 Solve *solve = solve_func[0];  
  97.                 if ((handle[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)solve,   
  98.                                     (VOID*)calc, 0, &thread_id[i])) != NULL)  //创建新线程  
  99.                 SetThreadAffinityMask(handle[i], i+1); //限定线程运行在哪个cpu上  
  100.             }  
  101.             WaitForSingleObject(handle[0],INFINITE);   //等待线程结束  
  102.             break;  
  103.         }  
  104.     case 2: //cpu1直线,cpu2正弦  
  105.         {  
  106.             for (int i = 0; i < NUM_CPUS; ++i)  
  107.             {  
  108.                 Func *calc = func[i];  
  109.                 Solve *solve = solve_func[i];  
  110.                 if ((handle[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)solve,   
  111.                                     (VOID*)calc, 0, &thread_id[i])) != NULL)  //创建新线程  
  112.                 SetThreadAffinityMask(handle[i], i+1); //限定线程运行在哪个cpu上  
  113.             }  
  114.             WaitForSingleObject(handle[0],INFINITE);   //等待线程结束  
  115.             break;  
  116.         }  
  117.         case 3: //cpu1直线,cpu2方波  
  118.         {  
  119.   
  120.             /*Func *calc = func[0]; 
  121.             Solve *solve = solve_func[0];*/  
  122.             if ((handle[0] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)solve_func[0],   
  123.                                 (VOID*)func[0], 0, &thread_id[0])) != NULL)  //创建新线程  
  124.             SetThreadAffinityMask(handle[0], 1); //限定线程运行在哪个cpu上  
  125.             Func *calc = func[2];  
  126.             Solve *solve = solve_func[1];  
  127.             if ((handle[1] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)solve,   
  128.                                 (VOID*)calc, 0, &thread_id[1])) != NULL)  //创建新线程  
  129.             SetThreadAffinityMask(handle[1], 2); //限定线程运行在哪个cpu上  
  130.             WaitForSingleObject(handle[0],INFINITE);   //等待线程结束  
  131.             break;  
  132.         }  
  133.         case 4: //cpu1正弦,cpu2方波  
  134.         {  
  135.             if ((handle[0] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)solve_func[1],   
  136.                                 (VOID*)func[1], 0, &thread_id[0])) != NULL)  //创建新线程  
  137.             SetThreadAffinityMask(handle[0], 1); //限定线程运行在哪个cpu上  
  138.             Func *calc = func[2];  
  139.             Solve *solve = solve_func[1];  
  140.             if ((handle[1] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)solve,   
  141.                                 (VOID*)calc, 0, &thread_id[1])) != NULL)  //创建新线程  
  142.             SetThreadAffinityMask(handle[1], 2); //限定线程运行在哪个cpu上  
  143.             WaitForSingleObject(handle[0],INFINITE);   //等待线程结束  
  144.             break;  
  145.         }  
  146.         default: break;  
  147.     }  
  148. }  
  149.   
  150. void main()  
  151. {  
  152.     run(1,0.5);  //cpu1 ,cpu2都输出50%的直线  
  153.     //run(2,0.5,30000); //cpu1 0.5直线,cpu2正弦周期30000  
  154.     //run(3);  //cpu1直线,cpu2方波  
  155.     //run(4,0.8,30000,0.95,0.5); //cpu1正弦,cpu2 0.95-0.5的方波  
  156. }  

下面更深入讨论,http://www.cnblogs.com/flyinghearts/archive/2011/03/22/1991965.html这篇博文很好,讨论了在双核情况下,每个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

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

[cpp]  view plain copy
  1. void solve(Func *calc)  
  2. {  
  3.   double tb = 0;  
  4.   while(1)   
  5.  {  
  6.     unsigned ta = get_time();  
  7.     double r = calc(tb);  
  8.     if (r < 0 || r > 1) r = 1;  
  9.     DWORD busy = r * GAP;  
  10.     while(get_time() - ta < busy) {}  
  11.     Sleep(GAP - busy);  
  12.     tb += GAP;  
  13.   }  
  14. }  

 

如果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.也就是说,只要确定了周期和计算次数,其它几个参数也都确定下来。

代码如下

[cpp]  view plain copy
  1. #include<iostream>  
  2. #include<cmath>  
  3. #include<windows.h>  
  4.   
  5. static int PERIOD = 60 * 1000; //周期ms  
  6. const int COUNT = 300;  //一个周期计算次数  
  7. const double GAP_LINEAR = 100;  //线性函数时间间隔100ms  
  8. const double PI = 3.1415926535898; //PI  
  9. const double GAP = (double)PERIOD / COUNT; //周期函数时间间隔  
  10. const double FACTOR = 2 * PI / PERIOD;  //周期函数的系数  
  11. static double Ratio = 0.5;  //线性函数的值 0.5即50%  
  12. static double Max=0.9; //方波函数的最大值  
  13. static double Min=0.1; //方波函数的最小值  
  14.   
  15. typedef double Func(double);  //定义一个函数类型 Func*为函数指针  
  16. typedef void Solve(Func *calc);//定义函数类型,参数为函数指针Func*  
  17. inline DWORD get_time()   
  18. {   
  19.     return GetTickCount(); //操作系统启动到现在所经过的时间ms  
  20. }  
  21. double calc_sin(double x)  //调用周期函数solve_period的参数  
  22. {    
  23.     return (1 + sin(FACTOR * x)) / 2; //y=1/2(1+sin(a*x))  
  24. }  
  25. double calc_fangbo(double x)  //调用周期函数solve_period的参数  
  26. {  
  27.     //方波函数  
  28.     if(x<=PERIOD/2) return Max;  
  29.     else return Min;  
  30. }  
  31.   
  32. void solve_period(Func *calc) //线程函数为周期函数  
  33. {  
  34.     double x = 0.0;  
  35.     double cache[COUNT];  
  36.     for (int i = 0; i < COUNT; ++i, x += GAP)   
  37.         cache[i] = calc(x);   
  38.     int count = 0;  
  39.     while(1)  
  40.     {  
  41.         unsigned ta = get_time();  
  42.         if (count >= COUNT) count = 0;  
  43.         double r = cache[count++];  
  44.         DWORD busy = r * GAP;  
  45.         while(get_time() - ta < busy) {}  
  46.         Sleep(GAP - busy);  
  47.   }  
  48. }  
  49.   
  50. void solve_linear(Func*)  //线程函数为线性函数,参数为空 NULL  
  51. {  
  52.     const unsigned BUSY =  Ratio * GAP_LINEAR;  
  53.     const unsigned IDLE = (1 - Ratio) * GAP_LINEAR;  
  54.     while(1)  
  55.     {  
  56.         unsigned ta = get_time();  
  57.         while(get_time() - ta < BUSY) {}  
  58.         Sleep(IDLE);  
  59.     }  
  60. }  
  61. //void solve_nonperiod(Func *calc) //非周期函数的处理,暂没实验  
  62. //{  
  63. //  double tb = 0;  
  64. //  while(1)  
  65. //  {  
  66. //    unsigned ta = get_time();  
  67. //    double r = calc(tb);  
  68. //    if (r < 0 || r > 1) r = 1;  
  69. //    DWORD busy = r * GAP;  
  70. //    while(get_time() - ta < busy) {}  
  71. //    Sleep(GAP - busy);  
  72. //    //tb += GAP;  
  73. //    tb += get_time() - ta;  
  74. //  }  
  75. //}  
  76.   
  77. void run(int i=1,double R=0.5,double T=60000,double max=0.9,double min=0.1)  
  78.      //i为输出状态,R为直线函数的值,T为周期函数的周期,max方波最大值,min方波最小值  
  79. {  
  80.     Ratio=R; PERIOD=T; Max=max; Min=min;  
  81.     Func *func[] = {NULL ,calc_sin,calc_fangbo};  //传给Solve的参数,函数指针数组  
  82.     Solve *solve_func[] = { solve_linear, solve_period};  //Solve函数指针数组  
  83.     const int NUM_CPUS = 2;  //双核,通用的可以用下面GetSystemInfo得到cpu数目  
  84.     HANDLE handle[NUM_CPUS];    
  85.     DWORD thread_id[NUM_CPUS]; //线程id  
  86.     //SYSTEM_INFO info;  
  87.     //GetSystemInfo(&info);   //得到cpu数目  
  88.     //const int num = info.dwNumberOfProcessors;  
  89.     switch(i)  
  90.     {  
  91.     case 1: //cpu1 ,cpu2都输出直线  
  92.         {  
  93.             for (int i = 0; i < NUM_CPUS; ++i)  
  94.             {  
  95.                 Func *calc = func[0];  
  96.                 Solve *solve = solve_func[0];  
  97.                 if ((handle[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)solve,   
  98.                                     (VOID*)calc, 0, &thread_id[i])) != NULL)  //创建新线程  
  99.                 SetThreadAffinityMask(handle[i], i+1); //限定线程运行在哪个cpu上  
  100.             }  
  101.             WaitForSingleObject(handle[0],INFINITE);   //等待线程结束  
  102.             break;  
  103.         }  
  104.     case 2: //cpu1直线,cpu2正弦  
  105.         {  
  106.             for (int i = 0; i < NUM_CPUS; ++i)  
  107.             {  
  108.                 Func *calc = func[i];  
  109.                 Solve *solve = solve_func[i];  
  110.                 if ((handle[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)solve,   
  111.                                     (VOID*)calc, 0, &thread_id[i])) != NULL)  //创建新线程  
  112.                 SetThreadAffinityMask(handle[i], i+1); //限定线程运行在哪个cpu上  
  113.             }  
  114.             WaitForSingleObject(handle[0],INFINITE);   //等待线程结束  
  115.             break;  
  116.         }  
  117.         case 3: //cpu1直线,cpu2方波  
  118.         {  
  119.   
  120.             /*Func *calc = func[0]; 
  121.             Solve *solve = solve_func[0];*/  
  122.             if ((handle[0] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)solve_func[0],   
  123.                                 (VOID*)func[0], 0, &thread_id[0])) != NULL)  //创建新线程  
  124.             SetThreadAffinityMask(handle[0], 1); //限定线程运行在哪个cpu上  
  125.             Func *calc = func[2];  
  126.             Solve *solve = solve_func[1];  
  127.             if ((handle[1] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)solve,   
  128.                                 (VOID*)calc, 0, &thread_id[1])) != NULL)  //创建新线程  
  129.             SetThreadAffinityMask(handle[1], 2); //限定线程运行在哪个cpu上  
  130.             WaitForSingleObject(handle[0],INFINITE);   //等待线程结束  
  131.             break;  
  132.         }  
  133.         case 4: //cpu1正弦,cpu2方波  
  134.         {  
  135.             if ((handle[0] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)solve_func[1],   
  136.                                 (VOID*)func[1], 0, &thread_id[0])) != NULL)  //创建新线程  
  137.             SetThreadAffinityMask(handle[0], 1); //限定线程运行在哪个cpu上  
  138.             Func *calc = func[2];  
  139.             Solve *solve = solve_func[1];  
  140.             if ((handle[1] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)solve,   
  141.                                 (VOID*)calc, 0, &thread_id[1])) != NULL)  //创建新线程  
  142.             SetThreadAffinityMask(handle[1], 2); //限定线程运行在哪个cpu上  
  143.             WaitForSingleObject(handle[0],INFINITE);   //等待线程结束  
  144.             break;  
  145.         }  
  146.         default: break;  
  147.     }  
  148. }  
  149.   
  150. void main()  
  151. {  
  152.     run(1,0.5);  //cpu1 ,cpu2都输出50%的直线  
  153.     //run(2,0.5,30000); //cpu1 0.5直线,cpu2正弦周期30000  
  154.     //run(3);  //cpu1直线,cpu2方波  
  155.     //run(4,0.8,30000,0.95,0.5); //cpu1正弦,cpu2 0.95-0.5的方波  
  156. }  

效果如图:

                 补充:我本人的电脑是Win10系统 i7-4700八核处理器,无奈不知道为什么使用以上方法很难实现,以上的效果都是我用虚拟机弄的winXP实现的。

比如当我用上面的多核的方法的时候,我把处理器核数改为8会出现如下的效果:

             

发现前四个处理器满载,其余也有不定占有率,我怀疑是不是这是win10的负载平衡导致的。


fusionchart做的实时监控cpu,内存变化曲线及柱状图 柱状图实时监控系统CPU,内存使用率和内存占用量,并绘制CPU及内存占用历史曲线图。下载后直接运行Index.html即可看到效果,是一个不错的demo 立即下载

相关推荐

vb c c# cpu使用率实时检测 获取CPU使用率

使用VB C语言 获取电脑CPU使用率,小巧实用,小内存使用,堪比鲁大师(说笑而已),完全代码公开,全解注释,直接F5运行,完全自己手动编写,适合有兴趣的猿员人们研究,桌面显示实时监控!!CPU使用率源代码,CPU使用率,源代码,VB源代码,C语言源代码。【猿友们可以对该项目进行内存优化,代码简化,使该小插件更小巧更适用更方便,可以去掉时间控件用异步,可以增加移动功能等,等待你去补充】 绝对重大强悍...

超频术语解析

超频相关BIOS术语

u010308704的博客 1万+

泛微ecology9 HRMwebservice接口实战:企业组织架构与人员信息同步指南

本文详细介绍了泛微ecology9 HRMwebservice接口在企业系统集成中的实战应用,重点解析了如何通过该接口实现组织架构与人员信息的双向同步。内容涵盖环境配置、核心接口调用、数据格式规范及常见错误排查,旨在帮助开发与运维工程师高效完成主数据同步,提升企业IT管理效率。

weixin_29323365的博客 495

使用 Prometheus 来避免 K8s CPU Limits 造成的事故

❝本文转自 charlieroro 的博客,原文:https://www.cnblogs.com/charlieroro/p/17074808.html,版权归原作者所有。欢迎投稿,投稿请添加微信好友:cloud-native-yang本文将介绍 Kubernetes 的 resource limits 是如何工作的、使用哪些 metrics 来设置正确的 limits 值、以及使用哪些指标来定位...

云原生实验室 1068

UART中断接收的实战陷阱:HAL库常见误区与性能调优指南

本文深入解析STM32 HAL库UART中断接收机制,揭示常见实战陷阱如数据溢出、中断优先级配置不当等,并提供性能调优方案。重点介绍如何使用空闲中断处理不定长数据、DMA与中断混合模式优化,以及工业级错误恢复与流量控制策略,帮助开发者构建稳定可靠的串口通信系统。

pea55的博客 747

忘记安卓锁屏密码怎么办?3种方法教你用ADB恢复访问(含gesture.key解密)

本文详细解析了安卓设备锁屏密码的存储与加密机制,特别是gesture.key文件的解密原理。针对遗忘密码的常见问题,提供了三种核心恢复方法:利用ADB调试接口删除密码文件、对gesture.key进行离线分析与解密,以及应对高版本系统的替代方案。重点介绍了通过ADB工具在Recovery模式下操作的具体步骤,帮助用户在合法合规前提下恢复设备访问权限。

php55的博客 955

c# 多线程 控制CPU不超过50%

原文地址:http://www.docin.com/p-1138045.html 编程之美 让CPU占用率曲线听你指挥   例子: public void PublishDetailItem(object obj)        {            Usp_Gif_GetGifInfosResult gif = obj as Usp_Gif_GetGifInfosResult;   ...

weixin_34025051的博客 397

保姆级教程:在RK3588 Android12设备树(DTS)中配置MIPI 8 Lane双通道与DSC显示

本文详细介绍了在RK3588 Android12平台上配置MIPI 8 Lane双通道与DSC显示的实战指南。通过设备树(DTS)参数详解、DSC参数计算与PPS配置、双通道同步机制实现等内容,帮助开发者高效完成高分辨率屏幕驱动配置,解决嵌入式显示系统开发中的常见挑战。

weixin_30905133的博客 399

C#实时曲线绘图—CPU使用率-利用WinForm

1.新建一个WinForm工程:2.找到工具箱中的数据下面的Chart控件,拖拽到界面上去,在属性里面修改Chart控件Name为cpuChart,修改series属性,ChartType选为Spline.操作过程如下图:3.最后再加个Button按钮,启动曲线绘制。后台代码Form1.cs如下所示:using System; using System.Collections.Generic; u...

他的博客 8749

MIPI video mode 和 command mode 的区别

1、何为LCD RAM? LCD 是指字面意思是液晶显示屏(Liquid Crystal Display), 而RAM: 随机存取存储器(Random-Access Memory),两者完全是风马牛不相及的东西。 下图是一个标准的LCD的爆炸图(不含TP),请注意图中红色mark的地方:控制IC-- LCD的大脑。所谓的LCD RAM自然是指此大脑是否包含RAM. 题外话<不感兴趣的...

精诚所至 4689

23、工业物流中的多智能体路径规划与碰撞处理策略

本文探讨了工业4.0背景下工业物流中的多智能体路径规划(MAPF)与碰撞处理策略。分析了自动导引车(AGV)等移动资源的应用现状,综述了主流路径规划算法如A*、D*Lite、M*等,以及集中式与分布式碰撞检测方法。重点比较了五种碰撞避免策略:路径交叉、优先级、起始时间调整、无交叉路径和速度调整,提出了基于环境条件的策略选择流程,并通过流程图展示了评估、组合、测试与优化的全过程。文章强调应根据订单不确定性、时间约束、优先级和生产组织等因素综合选择或组合策略,以提升物流效率与系统可靠性。

mac99的博客 125

编程之美 - 让CPU占用率曲线听你指挥

题目《让CPU占用率曲线听你指挥》问题写一个程序,让用户来决定Windows任务管理器(Task Manager)的CPU占用率。程序越精简越好,计算机语言不限。例如,可以实现下面三种情况:1.    CPU的占用率固定在50%,为一条直线;2.    CPU的占用率为一条直线,但是具体占用率由命令行参数决定(参数范围1~ 100);3.    CPU的占用率状态是一个正弦曲线

phphot 3340

Moviepy自动化剪辑视频中的广告

本教程展示了如何使用 Python 中的 MoviePy 库,通过检测和剪辑广告段落来实现视频内容的清洁播放。通过广告检测算法和 MoviePy 剪辑功能的结合,可以自动化处理视频,极大提升编辑效率。在学习和应用中,理解广告检测的原理及其实现方法尤为重要,以便针对不同类型的视频进行调整。此外,MoviePy 的灵活性使其适用于多种视频编辑场景,适合自动化内容制作与优化。

Mr数据杨 3408

编程之美:让CPU占用率曲线听你指挥

题目:写一个程序,让用户来决定Windows任务管理器(Task Manager)的CPU占用率。程序越精简越好,计算机语言不限。例如,可以实现下面三种情况:1.    CPU的占用率固定在50%,为一条直线; 2.    CPU的占用率为一条直线,但是具体占用率由命令行参数决定(参数范围1~ 100); 3.    CPU的占用率状态是一个正弦曲线。首先什么是CPU占用率?在任务管理器的一个刷新周期内,CPU忙(执行应用程序)的时间和刷新周期总时间的比率,就是CPU的占用率,也就是说,任务管理器中显示的是

wesweeky学习笔记 3万+

Quartus II编译时出现Error (119013): Current license file does not support the EP4CE6E22C6 device

Quartus II编译时出现Error (119013): Current license file does not support the EP4CE6E22C6 device, Quartus的安装过程不同于ISE/vivado的安装。“Current license file does not support”这种情况多出现在高版本的quartus中综合很久以前的代码,使用很早型号的FPGA或是CPLD。对于这种情况,就得在官网或是其他网站上下载包含所需Device的库文件。

夜半少年的博客 1万+

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

编程之美1 让CPU占用率曲线听你指挥

写一个程序,让用户决定Windows任务管理器(Task Manager)的CPU占用率。

Serena的博客 1030

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

如何让CPU的占用率曲线听你指挥

如何让CPU的占用率曲线听你指挥 写一个程序让用户来决定任务管理器的Cpu占用率。 如何让CPU的占用率曲线固定在50%,保持一条直线? 拿到这个问题不要着急,好好想一下。Think  about  it。什么是占用率?在一个Cpu的刷新周期里Cpu的使用与总的资源的百分比,那如何让CPU一会忙,一会闲呢?想一想,我们平时鼠标的移动都会造成Cpu曲线的变化,忙的时候我们可以执行空的循环,可

承续缘的信仰 1298

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

让cpu占用率曲线听你的指挥

解法一 int main() { for(; ; ) { for(int i = 0; i < 9600000; i++) ; Sleep(10); } return 0; } 解法二:使用gettickcount()

sanyuancap 804

让CPU占用率曲线听你指挥—微软技术面

学习自《程序员》2008年03月刊问题:写一个程序,让用户来决定Windows任务管理器(Task Manager)的CPU占用率。程序越精简越好,计算机语言不限。例如,可以实现下面三种情况:1. CPU的占用率固定在50%,为一条直线;2. CPU的占用率为一条直线,但是具体占用率由命令行参数决定(参数范围1-100);3. CPU的占用率状态是一个正弦曲线。分析与解法:

小北的家 1697

【编程之美】游戏之乐——让CPU占用率曲线听你指挥

让CPU占用率曲线听你指挥 问题描述:写一个程序,让用户来决定Windows任务管理器的CPU占用率曲线。程序约精简越好,计算机语言不限。例如,可以实现下面三种情况: 1.CPU的占用率固定在50%,为一条直线; 2.CPU的占用率为一条直线,具体占用率由命令行参数决定(参数范围1~·100); 3.CPU的占用率状态是一条正弦曲线。 理解要点:当系统中的程序或者在等待用户的输入,或者在...

小哲的博客 1195

【游戏之乐】让CPU占用率曲线听你指挥

写一个程序,让用户来决定Windows任务管理器(Task Manager)的CPU占用率。程序越精简越好,计算机语言不限。例如,可以实现下面三种情况: 1.CPU占用率固定50%,为一条直线 2.CPU占用率为一条直线,具体占用率由命令行决定(参赛1~100) 3.CPU占用率状态为一条正弦曲线

Lost in your eyes 939
上一篇: 机器学习做二元分类问题(二)
下一篇: 机器学习种类(三)
云金
博客等级 码龄11年 11粉丝 20原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值