获取系统CPU 使用率

               抓狂废话不多说了,网上存在一种获取CPU使用率的方法是有bug的。也不知道有多少使用该方法的人没注意这个问题了,反正我是看到有人直接复制了这个代码。

来看一下 FILETIME的结构:

typedef struct _FILETIME {
    DWORD dwLowDateTime;
    DWORD dwHighDateTime;
} FILETIME, *PFILETIME, *LPFILETIME;     

这个结构是64位的。ok,上个我调试的截图来证明一下,为什么出错

eax  是32的,shl eax,20h  也是还是他自己。没有任何改变;

注意到  __int64  和  FILETIME都是64位的。所以可以直接转换。

__int64 a = *(__int64*)&time1;   //只有一个赋值操作。什么左移,或操作,都不用了。可以少执行几条指令。

ok, 网上的代码一般可以参考,不可直接复制使用的。英文网站的代码,bug比较少。

ok, 展示一份,我参考外文,简化的代码吧。

SmarkLock.hpp

#pragma once
#include <wtypes.h>

class CSmartLock
{
public:
	CSmartLock(CRITICAL_SECTION& ref_cs)
	{
		m_cs = ref_cs;
		EnterCriticalSection(&m_cs);
	}

	~CSmartLock()
	{
		LeaveCriticalSection(&m_cs);
	}

private:
	CRITICAL_SECTION m_cs;
};

CPU.hpp

#pragma once

#include "SmarkLock.hpp"
#include <wtypes.h>

#define DELAY_DIFF	200
#define DATA_COUNT  (1000/DELAY_DIFF)

class CDelay
{
public:
	inline void Mark(){ m_mark = ::GetTickCount(); }
	inline int  MSec(){ return (::GetTickCount() - m_mark) & 0x7FFFFFFF; }

private:
	DWORD m_mark;
};

class CCPU
{
public:
	CCPU();
	~CCPU();

	int GetUsage();

private:

	static CDelay	s_delay;

	static int		s_count;
	static int      s_index;
	static int		s_lastCpu;
	static int      s_cpu[DATA_COUNT];

	static __int64 s_time;
	static __int64 s_idleTime;
	static __int64 s_kernelTime;
	static __int64 s_userTime;

	CRITICAL_SECTION m_lock;
};

CDelay	CCPU::s_delay;

int		CCPU::s_count = 0;
int		CCPU::s_index = 0;
int		CCPU::s_lastCpu = 0;
int		CCPU::s_cpu[DATA_COUNT];

__int64 CCPU::s_time = 0;
__int64 CCPU::s_idleTime = 0;
__int64 CCPU::s_kernelTime = 0;
__int64 CCPU::s_userTime = 0;

CCPU::CCPU()
{
	::InitializeCriticalSection(&m_lock);
	s_delay.Mark();
}

CCPU::~CCPU()
{
	::DeleteCriticalSection(&m_lock);
}

int CCPU::GetUsage()
{
	__int64 sTime;
	int sLastCpu;

#define LOCK_START	{ CSmartLock lock(m_lock);
#define LOCK_END	}
	
	LOCK_START
		sTime = s_time;
		sLastCpu = s_lastCpu;
	LOCK_END

	if (s_delay.MSec() <= DELAY_DIFF)
		return sLastCpu;

	__int64 time;
	__int64 idleTime;
	__int64 kernelTime;
	__int64 userTime;

	GetSystemTimeAsFileTime((LPFILETIME)&time);

	GetSystemTimes(
		(LPFILETIME)&idleTime,
		(LPFILETIME)&kernelTime,
		(LPFILETIME)&userTime
		);

	if (0 == sTime)
	{
		LOCK_START
			s_time			= time;
			s_idleTime		= idleTime;
			s_kernelTime	= kernelTime;
			s_userTime		= userTime;
			s_lastCpu		= 0;
		
			sLastCpu		= s_lastCpu;
		LOCK_END

		s_delay.Mark();
		return sLastCpu;
	}

	int iCpu;

	LOCK_START
		__int64 usr = userTime - s_userTime;
		__int64 ker = kernelTime - s_kernelTime;
		__int64 idl = idleTime - s_idleTime;

		__int64 sys = (usr + ker);
		if (0 == sys)
			iCpu = 0;
		else
			iCpu = (int)((sys - idl) * 100 / sys);

		s_time			= time;
		s_idleTime		= idleTime;
		s_kernelTime	= kernelTime;
		s_userTime		= userTime;

		s_cpu[(s_index++) % DATA_COUNT] = iCpu;
		s_count++;
		if (s_count > DATA_COUNT)
			s_count = DATA_COUNT;

		int i;
		iCpu = 0;
		for (i = 0; i < s_count; i++)
			iCpu += s_cpu[i];

		iCpu /= s_count;
		s_lastCpu = iCpu;
		
		sLastCpu = s_lastCpu;
	LOCK_END

	s_delay.Mark();
	return sLastCpu;
}
 
 

test.cpp

#include "CPU.hpp"
#include <stdio.h>

void main()
{
	CCPU testCpu;
	
	while (true)
	{
		static int count = 0;
		Sleep(DELAY_DIFF);
		count++;
		int iCpu = testCpu.GetUsage();
		if (count%(1000/DELAY_DIFF) == 0)
			printf("%d\n", iCpu);
	}
}



猜你喜欢

转载自blog.csdn.net/huanongying131/article/details/78723438
今日推荐