windows平台进程CPU占用率的计算

来源:互联网 发布:怎样利用网络挣钱 编辑:程序博客网 时间:2024/04/30 22:33

在进程的性能数据采集过程中,经常用到的一个性能指标就是进程的cpu占用率,下面给出它的计算方法及示例代码。

1、CPU占用率的定义

CPU占用率:指进程在一个时间段内消耗的CPU时间与该时间段长度的比值。

 

2、CPU占用率计算方法

根据上述定义,可以得到进程CPU占用率计算公式如下:

进程消耗的CPU时间 = 进程消耗的内核态时间 + 进程消耗的用户态时间,即 costTime = kernelTime + UserTime

进程的CPU占用率 = 进程消耗的CPU时间 / 刷新周期

 

3、CPU占用率计算涉及到的API

示例程序用到的主要API

GetSystemInfo    我们主要用它来获取系统中CPU核心个数

OpenProcess     用来打开指定进程的句柄

GetProcessTimes   根据OpenProcess返回的句柄,获取进程的KernelTime和UserTime

其它API(用于线程等其它情况下的计算)

OpenThread      获取指定线程的句柄

GetThreadTimes    根据OpenThread返回的句柄,获取线程的KernelTime和UserTime (可用于线程CPU占用率计算)

GetSystemTimes   获取总的CPU时间IdleTime KernelTime UserTime,可用于系统总的CPU占用率计算(注:多核CPU中返回的是所有CPU核时间的总和)

NtQuerySystemInformation  这是个native api,可以获取到许多信息。可以获得更细致的CPU使用率信息。(如每个核心的使用率)

 

4、示例代码

复制代码
  1 #include "stdafx.h"  2 #include <conio.h>  3 #include <windows.h>  4 #include <TlHelp32.h>  5 #include <process.h>  6   7 #define MY_PROCESS_ERROR(Condition) do{ if (!(Condition))  goto Exit0; } while (false)  8   9 static DWORD g_sdwTickCountOld = 0;                // 上一次的tick计数 10 static LARGE_INTEGER g_slgProcessTimeOld;        // 保存进程上一次的时间占用 11 static DWORD g_sdwProcessorCoreNum = 0;            // 处理器核心数 12 static HANDLE g_shExitEvent = NULL;                // 线程退出控制 13  14 typedef struct _TARGET_PROCESS 15 { 16     DWORD        dwProcessId;                    // 进程ID 17 }TARGET_PROCESS, *PTARGET_PROCESS; 18  19  20  21 /*@brief 获取找到的与指定进程名相符的第一个进程ID 22 * @param [in]        cpszExeFileName        进程可执行文件名(不带路径) 23 * @param [in/out]    dwPID                返回找到的名字符合的第一个进程ID 24 * @return 成功 : S_OK    失败 : 错误码 25 */ 26 HRESULT FindFirstProcessIdByName(const TCHAR* cpszExeFileName, DWORD &dwPID) 27 { 28     HRESULT hr = E_FAIL; 29  30     PROCESSENTRY32 pe = { 0 }; 31     HANDLE hSnapshot = NULL; 32  33     if (NULL == cpszExeFileName) 34     { 35         hr = HRESULT_FROM_WIN32(ERROR_BAD_ARGUMENTS); 36         goto Exit0; 37     } 38  39     pe.dwSize = sizeof(PROCESSENTRY32); 40     hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 41     if (INVALID_HANDLE_VALUE == hSnapshot) 42     { 43         hr = HRESULT_FROM_WIN32(GetLastError()); 44         goto Exit0; 45     }   46  47     if (FALSE == Process32First(hSnapshot, &pe)) 48     { 49         hr = HRESULT_FROM_WIN32(ERROR_NO_MORE_FILES); 50         goto Exit0; 51     } 52  53     hr = S_FALSE; 54     do 55     { 56         if (0 == _tcsicmp(cpszExeFileName, pe.szExeFile)) 57         { 58             dwPID = pe.th32ProcessID; 59             hr = S_OK; 60             break; 61         } 62     }while(Process32Next(hSnapshot, &pe)); 63  64 Exit0: 65     if(hSnapshot) 66     { 67         CloseHandle(hSnapshot); 68         hSnapshot = NULL; 69     } 70  71     return hr; 72 } 73  74 /*@brief 获取进程的Cpu占用率 75 * @param [in]    hProcess            进程句柄 76 * @param [in]    dwElepsedTime        取样间隔时间(毫秒) 77 * @return 成功 : cpu占用率    失败 : -1 78 */ 79 int GetProcessCpuPercent(const HANDLE hProcess, const DWORD dwElepsedTime) 80 { 81     int nProcCpuPercent = 0; 82     BOOL bRetCode = FALSE; 83  84     FILETIME CreateTime, ExitTime, KernelTime,UserTime; 85     LARGE_INTEGER lgKernelTime; 86     LARGE_INTEGER lgUserTime; 87     LARGE_INTEGER lgCurTime; 88  89     bRetCode = GetProcessTimes(hProcess, &CreateTime, &ExitTime, &KernelTime, &UserTime); 90     if (bRetCode) 91     { 92         lgKernelTime.HighPart = KernelTime.dwHighDateTime; 93         lgKernelTime.LowPart = KernelTime.dwLowDateTime; 94  95         lgUserTime.HighPart = UserTime.dwHighDateTime; 96         lgUserTime.LowPart = UserTime.dwLowDateTime; 97  98         lgCurTime.QuadPart = (lgKernelTime.QuadPart + lgUserTime.QuadPart) / 10000; 99         nProcCpuPercent = (int)((lgCurTime.QuadPart - g_slgProcessTimeOld.QuadPart) * 100 / dwElepsedTime);100         g_slgProcessTimeOld = lgCurTime;101         nProcCpuPercent = nProcCpuPercent / g_sdwProcessorCoreNum;102     }103     else104     {105         nProcCpuPercent = -1;106     }107 108     return nProcCpuPercent;109 }110 111 unsigned __stdcall WorkerThread(void *pArg)112 {113     HRESULT hr = E_FAIL;114 115     HANDLE hProcess = NULL;116     DWORD dwProcessId = 0;117     DWORD dwRetVal = 0;118     DWORD dwCurrentTickCount = 0;119     DWORD dwElapsedTime = 0;120     int nProcessCpuPercent = 0;121     122     TARGET_PROCESS *pTargetProcess = (TARGET_PROCESS *)pArg;123 124     dwProcessId = pTargetProcess->dwProcessId;125     hProcess = OpenProcess(PROCESS_QUERY_INFORMATION , FALSE, dwProcessId);126     MY_PROCESS_ERROR(hProcess);127 128     do 129     {130         dwRetVal = WaitForSingleObject(g_shExitEvent, 1000);131         if (WAIT_OBJECT_0 == dwRetVal ||132             WAIT_FAILED == dwRetVal133             )134         {135             break;136         }137 138         dwCurrentTickCount = GetTickCount();139         dwElapsedTime = dwCurrentTickCount - g_sdwTickCountOld;140         g_sdwTickCountOld = dwCurrentTickCount;141         nProcessCpuPercent = GetProcessCpuPercent(hProcess, dwElapsedTime);142         wprintf(L"cpu = %d\n", nProcessCpuPercent);143     } while (1);    144 Exit0:145     if (hProcess)146     {147         CloseHandle(hProcess);148         hProcess = NULL;149     }150     151     return 0;152 }153 154 int _tmain(int argc, _TCHAR* argv[])155 {156     HRESULT hr = E_FAIL;157     158     HANDLE hThread = NULL;159     unsigned int uiTid = 0;160     SYSTEM_INFO sysInfo = { 0 };161     TARGET_PROCESS struTargetProcess;162 163     if (argc > 1)164     {165         hr = FindFirstProcessIdByName(argv[1], struTargetProcess.dwProcessId);166         if (S_OK != hr)167         {168             _tprintf(_T("Can't find process \'%s\' ret=0x%X\n"), argv[1], hr);169             goto Exit0;170         }171 172         GetSystemInfo(&sysInfo);173         g_sdwProcessorCoreNum = sysInfo.dwNumberOfProcessors;174 175         g_shExitEvent = CreateEvent(NULL, TRUE, FALSE, NULL);176         MY_PROCESS_ERROR(g_shExitEvent);177 178         hThread = (HANDLE)_beginthreadex(NULL, 0, WorkerThread, &struTargetProcess, 0, &uiTid);179         MY_PROCESS_ERROR(hThread);180 181         _getch();182         SetEvent(g_shExitEvent);183         WaitForSingleObject(hThread, INFINITE);184     }185     else186     {187         _tprintf(_T("Please input a process name.\n"));188     }189 190 Exit0:191     if (hThread)192     {193         CloseHandle(hThread);194         hThread = NULL;195     }196 197     if (g_shExitEvent)198     {199         CloseHandle(g_shExitEvent);200         g_shExitEvent = NULL;201     }202 203     return 0;204 }
复制代码

 

from:http://www.cnblogs.com/xwj-pandababy/articles/2567498.html