1、通过查阅msdn,可以知道GetSystemTimes函数可以获取系统的时间,可以获得系统(自开机以来)处于Kernel状态下面的CPU时间,以及系统处于User状态下的时间,以及Idle的时间.我们只用Kernel时间和User时间, 不用Idle时间.
3、简单写个demo测试下,代码如下
#include <stdio.h>
#include <Windows.h>
#include <time.h>
#include <tchar.h>
__int64 DiffFileTime(FILETIME time1, FILETIME time2)
{
__int64 a = time1.dwHighDateTime << 32 | time1.dwLowDateTime;
__int64 b = time2.dwHighDateTime << 32 | time2.dwLowDateTime;
return b - a;
}
int main(int argc, char* argv[])
{
double cpuuse;
int idle, kernel, user;
FILETIME idleTime1, idleTime2;
FILETIME kernelTime1, kernelTime2;
FILETIME userTime1, userTime2;
do
{
GetSystemTimes(&idleTime1, &kernelTime1, &userTime1);
Sleep(1000);
GetSystemTimes(&idleTime2, &kernelTime2, &userTime2);
idle = (int)DiffFileTime(idleTime1, idleTime2);
kernel = (int)DiffFileTime(kernelTime1, kernelTime2);
user = (int)DiffFileTime(userTime1, userTime2);
if (kernel + user == 0)
cpuuse = 0.0;
else
cpuuse = abs((kernel + user - idle) * 100 / (kernel + user));//(总的时间-空闲时间)/总的时间=占用cpu的时间就是使用率
printf("cpu useage: %01f!\n", cpuuse);
} while (1);
return 0;
}
5、接下来,进一步对代码进行优化,将获取cpu的封装成一个通用的接口,优化后代码如下
#include <stdio.h>
#include <Windows.h>
#include <time.h>
#include <tchar.h>
__int64 DiffFileTime(FILETIME time1, FILETIME time2)
{
__int64 a = time1.dwHighDateTime << 32 | time1.dwLowDateTime;
__int64 b = time2.dwHighDateTime << 32 | time2.dwLowDateTime;
return b - a;
}
double GetCpuUsage()
{
double cpuuse;
int idle, kernel, user;
FILETIME idleTime1, idleTime2;
FILETIME kernelTime1, kernelTime2;
FILETIME userTime1, userTime2;
GetSystemTimes(&idleTime1, &kernelTime1, &userTime1);
Sleep(1000);
GetSystemTimes(&idleTime2, &kernelTime2, &userTime2);
idle = (int)DiffFileTime(idleTime1, idleTime2);
kernel = (int)DiffFileTime(kernelTime1, kernelTime2);
user = (int)DiffFileTime(userTime1, userTime2);
if (kernel + user == 0)
cpuuse = 0.0;
else
cpuuse = abs((kernel + user - idle) * 100 / (kernel + user));//(总的时间-空闲时间)/总的时间=占用cpu的时间就是使用率
return cpuuse;
}
int main(int argc, char* argv[])
{
double cpuusage = 0;
do
{
cpuusage = GetCpuUsage();
printf("cpu useage: %01f!\n", cpuuse);
} while (1);
return 0;
}
6、上面的写法其实还有一个缺点,就是获取的时候需要延时一秒,这个对直接调用不太好,可以使用线程或者定时器和加锁保护读写同步来代替,参考代码如下
#include <stdio.h>
#include <Windows.h>
#include <time.h>
#include <tchar.h>
__int64 DiffFileTime(FILETIME time1, FILETIME time2)
{
__int64 a = time1.dwHighDateTime << 32 | time1.dwLowDateTime;
__int64 b = time2.dwHighDateTime << 32 | time2.dwLowDateTime;
return b - a;
}
CRITICAL_SECTION slock;
double scpuuse = 0;
void SetCpuUsage(double cpu)
{
EnterCriticalSection(&slock);
scpuuse = cpu;
LeaveCriticalSection(&slock);
}
double GetCpuUsage()
{
double cpu = 0;
EnterCriticalSection(&slock);
cpu = scpuuse;
LeaveCriticalSection(&slock);
return cpu;
}
DWORD WINAPI ThreadProc(LPVOID lpParam)
{
int idle, kernel, user;
FILETIME idleTime1, idleTime2;
FILETIME kernelTime1, kernelTime2;
FILETIME userTime1, userTime2;
do
{
GetSystemTimes(&idleTime1, &kernelTime1, &userTime1);
Sleep(1000);
GetSystemTimes(&idleTime2, &kernelTime2, &userTime2);
idle = (int)DiffFileTime(idleTime1, idleTime2);
kernel = (int)DiffFileTime(kernelTime1, kernelTime2);
user = (int)DiffFileTime(userTime1, userTime2);
if (kernel + user == 0)
SetCpuUsage(0.0);
else
SetCpuUsage(abs((kernel + user - idle) * 100 / (kernel + user)));//(总的时间-空闲时间)/总的时间=占用cpu的时间就是使用率
} while (1);
}
int main(int argc, char* argv[])
{
HANDLE m_hThread;
InitializeCriticalSection(&slock);
m_hThread = CreateThread(NULL, 0, ThreadProc, 0, 0, NULL);//创建新线程
do
{
printf("cpu useage: %01f!\n", GetCpuUsage());
Sleep(1000);
} while (1);
CloseHandle(m_hThread);
DeleteCriticalSection(&slock);
return 0;
}