计算WINOWS C P U指标

在Windows中计算CPU利用率的方法是使用SystemProcessorPerformanceInformation参数反复调用NtQuerySystemInformation函数,然后根据返回的IdleTime、KernelTime和UseTime值,分别使用后一次调用获得的值减去前一次调用获得的值,得到各个增量值,然后使用一个除法就可以得到CPU利用率。

这里唯一需要注意的是KernelTime成员值包含IdleTime和核心调用的使用时间。

当使用SystemBasicInformation 调用 NtQuerySystemInformation 来试图获取CPU个数时会失败,返回0xC0000004错误码,可以使用GetSystemInfo函数获得CPU的个数。

CPU利用率的计算公式如下:

100.0 * (IdleTime –PrevIdleTime) / (KernelTime + UserTime – PrevKernelTime – PrevUserTime)

注1:实际内核时间(ActualKernelTime)= KernelTime– IdleTime,内核时间-空闲时间。

注2:全部CPU时间(CpuTime)= UserTime +KernelTime,用户时间+内核时间。

 

CPP

#include "StdAfx.h"
#include "PUCoreUsage.h"

CPUCoreUsage::CPUCoreUsage(void)
{
	m_iCPUCoreNum = GetCpuCoreNum();
	printf("CPU Core Num:%d\n",m_iCPUCoreNum);
	m_pCurcputimes = new SystemCpuTimes[m_iCPUCoreNum];
	m_pNewcputimes = new SystemCpuTimes[m_iCPUCoreNum];
	m_iCurValid = false;
}
CPUCoreUsage::~CPUCoreUsage(){
	if (m_pCurcputimes)
		delete m_pCurcputimes;
	if (m_pNewcputimes)
		delete m_pNewcputimes;
}

int CPUCoreUsage::GetCpuCoreNum(){
	SYSTEM_INFO  sysInfo;
	GetSystemInfo(&sysInfo);
	if( sysInfo.dwNumberOfProcessors <= 0){
		return 1;
	}
	return sysInfo.dwNumberOfProcessors;
}

int CPUCoreUsage::GetSystemCpuTimes(SystemCpuTimes * cputimes, int num)
{
	
	// dynamic linking is mandatory to use NtQuerySystemInformation
	HINSTANCE hNtDll =LoadLibrary("ntdll.dll");
	if (hNtDll == NULL) {
		fprintf(stderr, "LoadLibraryntdll.dll failed.\n");
		return -1;
	}
	// gets NtQuerySystemInformation address
	NTQSI_PROC NtQuerySystemInformation =(NTQSI_PROC)GetProcAddress(hNtDll, "NtQuerySystemInformation");
	if (NtQuerySystemInformation == NULL) {
		FreeLibrary(hNtDll);
		return -2;
	}
	SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* sppi
		= new SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION[num];
	if (sppi == NULL) {
		FreeLibrary(hNtDll);
		return -3;
	}
	// Get CPU time informations
	if (NtQuerySystemInformation(SystemProcessorPerformanceInformation,
		sppi, num*
		sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION), NULL) != 0) {
			FreeLibrary(hNtDll);
			delete []sppi;
			return -4;
	}
	// computes system global times summingeach processor value
	for (DWORD i = 0; i <num; i++) {
		cputimes[i].user = sppi[i].UserTime.QuadPart;
		cputimes[i].kernal =  sppi[i].KernelTime.QuadPart;
		cputimes[i].idle =  sppi[i].IdleTime.QuadPart;
		cputimes[i].total =  cputimes[i].user + cputimes[i].kernal;
	}
	FreeLibrary(hNtDll);
	delete []sppi;
	return 0;
}


int  CPUCoreUsage::GetCPUCoreUsageInfo(double *usage ,int num) 
 {
     if (num<m_iCPUCoreNum){
		return -3;
	 }
	 if (NULL == usage){
		 return -2;
	 }
      if (0 != GetSystemCpuTimes(m_pNewcputimes,m_iCPUCoreNum))
        return -1;
	  if (!m_iCurValid){
		  SystemCpuTimes * temp = m_pNewcputimes;
		  m_pNewcputimes = m_pCurcputimes;
		  m_pCurcputimes = temp;
		  m_iCurValid = true;
		  return 1;
	  }

      double total = 0;
      int count = 0;
      for (int i = 0; i < m_iCPUCoreNum; i++) {
		 if (m_pNewcputimes[i].total - m_pCurcputimes[i].total < 1000){
			return -4;
		 }
		 usage[i] = 1.0f - (m_pNewcputimes[i].idle - m_pCurcputimes[i].idle)/
			 (m_pNewcputimes[i].total - m_pCurcputimes[i].total);
      }
	  usage[m_iCPUCoreNum] = 1.0f - total/count;
	  {
		  SystemCpuTimes * temp = m_pNewcputimes;
		  m_pNewcputimes = m_pCurcputimes;
		  m_pCurcputimes = temp;
	  }
	  return 0;
  }

H

class CPUCoreUsage
{
public:
	CPUCoreUsage(void);
	~CPUCoreUsage();
	int GetCpuCoreNum();
	int GetCPUCoreUsageInfo(double *usage ,int num);
	int GetSystemCpuTimes(SystemCpuTimes * cputimes, int num);
private:
	int m_iCPUCoreNum;
	bool m_iCurValid;
	SystemCpuTimes * m_pCurcputimes;
	SystemCpuTimes * m_pNewcputimes;
};



int main()
{
	CPUCoreUsage cpuCoreUsage;
	SetProcessAffinityMask(GetCurrentProcess(),0x00000002);
	int iCPUCoreNum = cpuCoreUsage.GetCpuCoreNum();
	printf("CPU Core Num:%d\n",iCPUCoreNum);
 
	double *usage = new double[iCPUCoreNum];
	while(1){
		int re = cpuCoreUsage.GetCPUCoreUsageInfo( usage , iCPUCoreNum);
		if (re == 0){
			double avgUsage = 0.0f;
			printf("this pielod info:\n");
			for(int i=0 ;i<iCPUCoreNum;i++){
				avgUsage += usage[i];
				printf("CPU%d : %f\n",i,usage[i]);
			}
			avgUsage /= iCPUCoreNum;
			printf(" Avg CPU : %f\n",avgUsage);
		}else{
			printf("result %d\n",re);
		}
		
		Sleep(200);
	}

	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值