C++ 实时获取CPU使用率的类 (源码)


说明:1。内部使用timer定时器,自动刷新,使外部使用十分明了;2。主程序要有消息循环


//=========================================================
//
// Copyright (c) 2000-2004  iWise Technologies,Co. Ltd.
// All Rights Reserved.
//
// Product: iW988
// File: CpuUsage.h
// Created: 天衣有缝
//  
// Description:
//     ValueAdded main program for iW988.
//                   Contact:
//                       [email protected]
//
//=========================================================

#pragma once 

#define SystemBasicInformation 0 
#define SystemPerformanceInformation 2 
#define SystemTimeInformation 3 

#define Li2Double(x) ((double)((x).HighPart) * 4.294967296E9 + (double)((x).LowPart)) 

class CCpuUsage
{
public:
	CCpuUsage();
	~CCpuUsage();
	
public:
	int GetCpuUsage();                       //得到系统cpu利用率
	int SetRefreshInterval(int milli_sec);   //定时刷新间隔
	
private:
	//类型定义
	typedef LONG (WINAPI *PROCNTQSI)(UINT,PVOID,ULONG,PULONG);
	
	typedef struct
	{
		DWORD dwUnknown1;
		ULONG uKeMaximumIncrement;
		ULONG uPageSize;
		ULONG uMmNumberOfPhysicalPages;
		ULONG uMmLowestPhysicalPage;
		ULONG uMmHighestPhysicalPage;
		ULONG uAllocationGranularity;
		PVOID pLowestUserAddress;
		PVOID pMmHighestUserAddress;
		ULONG uKeActiveProcessors;
		BYTE bKeNumberProcessors;
		BYTE bUnknown2;
		WORD wUnknown3;
	} SYSTEM_BASIC_INFORMATION;
	
	typedef struct
	{
		LARGE_INTEGER liIdleTime;
		DWORD dwSpare[76];
	} SYSTEM_PERFORMANCE_INFORMATION;
	
	typedef struct
	{
		LARGE_INTEGER liKeBootTime;
		LARGE_INTEGER liKeSystemTime;
		LARGE_INTEGER liExpTimeZoneBias;
		ULONG uCurrentTimeZoneId;
		DWORD dwReserved;
	} SYSTEM_TIME_INFORMATION;
	
	//变量定义
	SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo;
	SYSTEM_TIME_INFORMATION SysTimeInfo;
	SYSTEM_BASIC_INFORMATION SysBaseInfo;       double dbIdleTime;
	double dbSystemTime;
	
	LONG status;
	
	LARGE_INTEGER liOldIdleTime;
	LARGE_INTEGER liOldSystemTime;
	
	PROCNTQSI NtQuerySystemInformation;
	
	int m_nCpuUsage;
	
	//定时
	HWND m_hWnd;
	int  m_nRefreshInterval;//默认为1000毫秒
	int  m_nTimerID;
	
private:
	static void CalcCpuUsage(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime);
	int OnTimer();
};

inline CCpuUsage::CCpuUsage()
{
    //
    m_hWnd = NULL;
    m_nRefreshInterval = 1000;
    m_nTimerID = 1000;
    m_nCpuUsage = 0;
	
    //
    memset(&liOldIdleTime  ,   0, sizeof(LARGE_INTEGER));
    memset(&liOldSystemTime,   0, sizeof(LARGE_INTEGER)); 
	
    //
    NtQuerySystemInformation = (PROCNTQSI)GetProcAddress(
		GetModuleHandle("ntdll") , "NtQuerySystemInformation");
    if (!NtQuerySystemInformation)
        return;
	
    // get number of processors in the system
    status =NtQuerySystemInformation(SystemBasicInformation,&SysBaseInfo,sizeof(SysBaseInfo),NULL);
    if (status != NO_ERROR)
        return;
	
    // create control for timer
    m_hWnd = ::CreateWindow("static", "", 0, 0, 0, 0, 0, NULL, NULL, 0, NULL);
    ::SetWindowLong(m_hWnd , GWL_USERDATA , (long)(this) );
	
    TIMERPROC tp = (TIMERPROC)CalcCpuUsage;
    SetTimer(m_hWnd , m_nTimerID, m_nRefreshInterval, tp);
	
}

inline CCpuUsage::~CCpuUsage()
{
    KillTimer(m_hWnd , m_nTimerID);
    DestroyWindow(m_hWnd);
}

inline void CCpuUsage::CalcCpuUsage(
									HWND hwnd,
									UINT uMsg,
									UINT_PTR idEvent,
									DWORD dwTime
									){
    CCpuUsage* pCpu = (CCpuUsage*)::GetWindowLong(hwnd , GWL_USERDATA);
	
    if ( pCpu )
    {
        pCpu->OnTimer();
    }
	
}

inline int CCpuUsage::OnTimer()
{
    status =NtQuerySystemInformation(SystemTimeInformation,&SysTimeInfo,sizeof(SysTimeInfo),0);
	
    if (status!=NO_ERROR)
        return 0;
	
    // get new CPU's idle time
    status =NtQuerySystemInformation(SystemPerformanceInformation,&SysPerfInfo,sizeof(SysPerfInfo),NULL);
    if (status != NO_ERROR)
        return 0;
	
    // if it's a first call - skip it
    if (liOldIdleTime.QuadPart != 0)
    {
		// CurrentValue = NewValue - OldValue
        dbIdleTime = Li2Double(SysPerfInfo.liIdleTime) - Li2Double(liOldIdleTime);
        dbSystemTime = Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime);
		
		// CurrentCpuIdle = IdleTime / SystemTime
        dbIdleTime = dbIdleTime / dbSystemTime;
		
		// CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors
		dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SysBaseInfo.bKeNumberProcessors+ 0.5;
		
		m_nCpuUsage = (UINT)dbIdleTime;
	}
	
    // store new CPU's idle and system time
    liOldIdleTime = SysPerfInfo.liIdleTime;
    liOldSystemTime = SysTimeInfo.liKeSystemTime;
	
    // wait one second
	
    return 0;
}

inline int CCpuUsage::GetCpuUsage()
{
    return m_nCpuUsage;
}

inline int CCpuUsage::SetRefreshInterval(int milli_sec)
{
    m_nRefreshInterval = milli_sec;
	
    if ( m_hWnd )
    {
        TIMERPROC tp = (TIMERPROC)CalcCpuUsage;
        SetTimer(m_hWnd, m_nTimerID, m_nRefreshInterval ,tp);
    }
	
    return 0;
	
}

你可能感兴趣的:(C/C++)