windows C++
1. 系统CPU利用率
理论支持
1.CPU利用率:CPU工作时间与总时间的比值。
2.Windows下任务管理器CPU利用率的由来:
a.CPU使用率:在任务管理器的刷新周期内CPU工作时间与刷新周期的比值。
b.任务管理器默认的刷新周期是1s。
3.windows下,CPU只会处于两种状态:陷入内核和陷入用户。
4.若干公式:
a.利用率 = CPU工作时间 / 时间间隔 (一段时间内,如1s内)
b.工作时间 = 内核态工作时间 +用户态工作时间。
c.时间间隔 = 工作时间 + 空闲时间 = 内核时间 + 用户时间。
5.当空闲时,CPU进入内核执行System Idle Process。打开任务管理器->进程->最下面,System Idle Process所持有CPU即此刻空闲CPU。故内核时间等于内核态工作时间与CPU整体空闲时间之和。
综上所述:
A.CPU利用率 = (用户时间 + 内核时间 - 空闲时间) / (用户时间 + 内核时间)
B.CPU利用率 = (用户时间
+ 内核时间 - 空闲时间)/
间隔时间
函数和结构体
1.函数GetSystemTimes
原型:BOOL GetSystemTimes(LPFILETIME lpIdleTime, LPFILETIME lpKernelTime, LPFILETIME lpUserTime)
返回值:成功返回0,否则非0
功能:获取CPU处于空闲、内核、用户态的时间。
A.自开机以来
B.所有CPU的时间和
2.FILETIME结构
typedef struct _FILETIME {
DWORD dwLowDateTime;
DWORD dwHighDateTime;
} FILETIME, *PFILETIME;
DWORD = unsigned long,4字节32位
3.提取FILETIME时间:
方法一
ULARGE_INTEGER ul;
ul.HighPart = ft.dwHighDateTime;
ul.LowPart = ft.dwLowDateTime;
ul.QuadPart即ft代表的时间,单位0.1微秒
方法二
ULONGLONG ull = ft.dwHighDateTime;
ull = ull<<32 | ft.dwLowDateTime;
4.ULARGE_INTEGER结构:
typedef union _ULARGE_INTEGER { struct { DWORD LowPart; DWORD HighPart; }; struct { DWORD LowPart; DWORD HighPart; } u; ULONGLONG QuadPart; } ULARGE_INTEGER, *PULARGE_INTEGER;
ULARGE_INTEGER实为联合体,专用于表示64位无符号大长整形。
将FILETIME还原为64位无符号大长整形:将FILETIME高32位、低32位分别赋值给ULARGE_INTEGER高、低32位,然后ULARGE_INTEGER的QuadPart即结果。
程序实现
ULONGLONG CompareFileTime(const FILETIME &ft1, const FILETIME &ft2) { ULARGE_INTEGER ul1; ul1.HighPart = ft1.dwHighDateTime; ul1.LowPart = ft1.dwLowDateTime; ULARGE_INTEGER ul2; ul2.HighPart = ft2.dwHighDateTime; ul2.LowPart = ft2.dwLowDateTime; return ul2.QuadPart - ul1.QuadPart; } int GetSystemCpu(){ FILETIME ftPreIdle, ftPreUser, ftPreKernel; FILETIME ftIdle, ftUser, ftKernel; if(!GetSystemTimes(&ftPreIdle, &ftPreKernel, &ftPreUser)) { std::cout<<"First GetSystemTimes Error"<<std::endl; return; } Sleep(n); if(!GetSystemTimes(&ftIdle, &ftKernel, &ftUser)) { std::cout<<"Second GetSystemTimes Error"<<std::endl; return; } ULONGLONG ullIdle = CompareFileTime(ftPreIdle, ftIdle); ULONGLONG ullKernel = CompareFileTime(ftPreKernel, ftKernel); ULONGLONG ullUser = CompareFileTime(ftPreUser, ftUser); double dCpu1 = (ullKernel+ullUser-ullIdle)*100.0 / (ullKernel+ullUser); double dCpu2 = (ullKernel+ullUser-ullIdle)*100.0 / (n*1000*10*iCpuNum); return static_cast<int>(dCpu1+0.5); }
2. 进程CPU利用率
如果说系统CPU利用率是一段时间内所有进程运行时间占总时间的比值,则进程CPU利用率即为一段时间内该进程运行时间占总时间的比值,故:
进程CPU利用率 = 进程运行时间 / 总时间
辅助函数
1.函数GetProcessTimes
原型:BOOL GetProcessTimes(
HANDLE hProcess, LPFILETIME lpCreationTime, LPFILETIME lpExitTime, LPFILETIME lpKernelTime, LPFILETIME lpUserTime)
返回值:成功返回0,否则非0
功能:获取进程创建时间、退出时间、内核时间、用户时间。
A.创建时间和退出时间是UNIX时间戳。
B.若进程尚未退出,lpExitTime值不确定。
C.lpKernelTime和lpUserTime要考虑多处理器情况。
D.即便不需要创建时间和退出时间也必须保证传入的lpCreationTime和lpExitTime有意义。
程序实现
HANDLE GetProcessHandle(const std::string &sProcessName) { PROCESSENTRY32 pe32; pe32.dwSize = sizeof(pe32); HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); BOOL bMore = Process32First(hProcessSnap, &pe32); while(bMore) { if(!sProcessName.compare(pe32.szExeFile)) { HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID); return hProcess; } bMore=::Process32Next(hProcessSnap,&pe32); } std::cout<<"Not Found The Process Of Server:"<<sProcessName<<std::endl; return INVALID_HANDLE_VALUE; } int GetProcessCpu(const std::string &sProcessName) { HANDLE hProcess = GetProcessHandle(sProcessName); if(INVALID_HANDLE_VALUE == hProcess) { std::cout<<"Get Process Handle Fail"<<std::endl; return -1; } SYSTEM_INFO si; GetSystemInfo(&si); int iCpuNum = si.dwNumberOfProcessors; FILETIME ftPreKernelTime, ftPreUserTime; FILETIME ftKernelTime, ftUserTime; FILETIME ftCreationTime, ftExitTime; if(!GetProcessTimes(hProcess, &ftCreationTime, &ftExitTime, &ftPreKernelTime, &ftPreUserTime)) { std::cout<<"First GetProcessTimes Error:"<< GetLastError()<<std::endl; return -1; } Sleep(INTERVAL); if(!GetProcessTimes(hProcess, &ftCreationTime, &ftExitTime, &ftKernelTime, &ftUserTime)) { std::cout<<"GetProcessTimes Error:"<< GetLastError()<<std::endl; return -1; } ULONGLONG ullKernelTime = CompareFileTime(ftPreKernelTime, ftKernelTime); ULONGLONG ullUserTime = CompareFileTime(ftPreUserTime, ftUserTime); double dCpu = (ullKernelTime+ullUserTime)*100.0 / (cpuNum*INTERVAL*10000); return static_cast<int>(dCpu + 0.5); }