`

让CPU占用率听你指挥

 
阅读更多

CPU占用率显示为y=A+Asin(x)曲线

//基本思路是新建一线程,让这个线程只在某一cpu上运行。这个线程的作用是控制单个cpu的占用率。

#include "stdafx.h"	//建工程时自动引入
#include<stdio.h>
#include<windows.h>
#include <stdlib.h>
#include <math.h>


const double SPLIT = 0.01;
const int COUNT = 200;
const double PI = 3.1415926;
const int INTERVAL = 300;

/*
	1. #define WINAPI __stdcall
	__stdcall是新标准的C/C++函数调用方法,从底层上说,使用这种方法参数的进栈顺序和
	标准C调用(_cdecl方法)相同,都是从右向左。但是__stdcall(WINAPI)采用自动清栈,而
	_cdecl采用手工清栈。
	
	2. 回调(Windows来调用的)
*/
static DWORD WINAPI myProc(LPVOID p)//WINAPI:回调,参数从右向左入栈,自动清栈
{
 DWORD busySpan[COUNT];
 DWORD idleSpan[COUNT];

 int half = INTERVAL / 2;
 double radian = 0.0;//radian弧度,这里指角度值(横坐标)

 for (int i=0; i<COUNT; i++)
 {
  busySpan[i] = (DWORD)(half + half * sin(PI * radian));//y=sin(x)曲线必须向上平移INTERVAL,否则无法到达横轴以下部分
  idleSpan[i] = INTERVAL - busySpan[i];
  radian += SPLIT;
 }

 DWORD startTime = 0;
 int j=0;//j是一个循环的时间坐标
 while (true)
 {
  j=j%COUNT;
  startTime = GetTickCount();
  while ( (GetTickCount() - startTime) <= busySpan[j])
  {
   ;//牢记:即使不做任何操作的while()也不会被挂起,它是一直工作的:{
  }
  Sleep(idleSpan[j]);
  j++;
 }
}


int main(int argc, char* argv[])
{
char szbuf[200];//传给线程的参数
 DWORD id;
 HANDLE h = CreateThread(NULL, 0, myProc, &szbuf, CREATE_SUSPENDED, &id);
 //CREATE_SUSPENDED先挂起线程,设置环境,再ResumeThread(h)
 if (NULL == h)
 {
  printf("error /n");
  return 0;
 }

 SetThreadAffinityMask(h, 1);//?1

 ResumeThread(h);

 /*
	//直接写成不完善:
	::WaitForSingleObject(h,INFINITE);
	::CloseHandle(h);
 */
 if (WaitForSingleObject(h, INFINITE) != WAIT_OBJECT_0)
 {
  CloseHandle(h);
  printf("error /n");
  return 0 ;
 }

 CloseHandle(h);


	return 0;
}
 

 

相关知识:

      1. Windows线程

 

 

      2. WaitForSingleObject(handle,INFINITE)

 

      DWORD   WaitForSingleObject(
        HANDLE   hHandle, //   handle   of   object   to   wait   for
        DWORD   dwMilliseconds   //   time-out   interval   in   milliseconds
      );
参数:
    hHandle   :等待对象句柄。
    dwMillSeconds:   指定以毫秒为单位的超时间隔。
返回值:
    WAIT_ABANDONED:   指定对象是互斥对象,在线程被终止前,线程没有释放互斥对象。互斥对象的所属关系被授予调用线程,并且该互斥对象被置为非信号态。
    WAIT_OBJECT_0:     指定对象的状态被置为信号状态。
    WAIT_TIMEOUT:       超时,并且对象的状态为非信号态。
    WAIT_FAILED:         调用失败。

 

 

      3. 使用多核——线程占用某些CPU:


我的笔记本有4个CPU
    经过试验,
        SetThreadAffinityMask(h,1)使用CPU1
        SetThreadAffinityMask(h,2)使用CPU2
        SetThreadAffinityMask(h,4)使用CPU3
        SetThreadAffinityMask(h,5)使用CPU4

 

以下是转载的文章:http://blog.sina.com.cn/s/blog_4a657c5a0100f4q6.html

 

通过调用SetThreadAffinityMask,就能为各个线程设置亲缘性屏蔽: 


  DWORD_PTR  SetThreadAffinityMask  ( 
      HANDLE  hThread,                                  //  handle  to  thread 
      DWORD_PTR  dwThreadAffinityMask    //  thread  affinity  mask 
  ); 
  该函数中的  hThread  参数用于指明要限制哪个线程,  dwThreadAffinityMask用于指明该线程 
  能够在哪个CPU上运行。dwThreadAffinityMask必须是进程的亲缘性屏蔽的相应子集。返回值 
  是线程的前一个亲缘性屏蔽。例如,可能有一个包含4个线程的进程,它们在拥有4个CPU的计算机上运行。如果这些线程中的一个线程正在执行非常重要的操作,而你想增加某个CPU始终可供它使用的可能性,为此你对其他3个线程进行了限制,使它们不能在CPU  0上运行,而只能在CPU  1、2和3上运行。因此,若要将3个线程限制到CPU  1、2和3上去运行,可以这样操作: 
   
  //线程0只能在cpu  0上运行 
  SetThreadAffinityMask(hThread0,0x00000001); 
  //线程1,2,3只能在cpu  1,2,3上运行 
  SetThreadAffinityMask(hThread1,0x0000000E); 
  SetThreadAffinityMask(hThread2,0x0000000E); 
  SetThreadAffinityMask(hThread3,0x0000000E);
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics