经过比对,发现procexp和任务管理器在计算进程cpu占用上面存在很大的差异,经过研究发现,procexp显示的是正确的,而任务管理器显示的是错误的,任务管理器是用以前老的方式计算的。
新的cpu计算原理应该是:
进程CPU占用率 = 进程消耗CPU时间 / 所有进程消耗CPU总时间 * 100%
CycleTime:周期时间(即从进程启动开始到当前所消耗的CPU时间总和)
所有进程消耗CPU总时间 = 所有进程的周期时间 + 内核时间(DPC以及中断服务)
Idle进程消耗的CPU时间 = 每个核消耗的CPU时间相加
以下是具体实现:
#include <conio.h>
#include <atlbase.h>
#include <iostream>
#include "SysProcess.h"
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) >= 0)
#define NT_INFORMATION(Status) ((((ULONG)(Status)) >> 30) == 1)
#define NT_WARNING(Status) ((((ULONG)(Status)) >> 30) == 2)
#define NT_ERROR(Status) ((((ULONG)(Status)) >> 30) == 3)
#define SYSTEM_IDLE_PROCESS_ID ((HANDLE)0)
#define FIND_FIRST_PROCESS(Processes) ((PSYSTEM_PROCESS_INFORMATION)(Processes))
#define FIND_NEXT_PROCESS(Process) ( \
((PSYSTEM_PROCESS_INFORMATION)(Process))->NextEntryOffset ? \
(PSYSTEM_PROCESS_INFORMATION)((PCHAR)(Process) + \
((PSYSTEM_PROCESS_INFORMATION)(Process))->NextEntryOffset) : \
NULL \
)
#define PhUpdateDelta(DltMgr, NewValue) \
((DltMgr)->Delta = (NewValue) - (DltMgr)->Value, \
(DltMgr)->Value = (NewValue), (DltMgr)->Delta)
typedef NTSTATUS (NTAPI *NTQUERYSYSTEMINFORMATION)(IN SYSTEM_INFORMATION_CLASS, IN OUT PVOID, IN ULONG, OUT PULONG OPTIONAL);
typedef NTSTATUS (NTAPI *NTQUERYINFORMATIONPROCESS)(IN HANDLE ProcessHandle,
IN PROCESSINFOCLASS ProcessInformationClass,
OUT PVOID ProcessInformation,
IN ULONG ProcessInformationLength,
OUT PULONG ReturnLength OPTIONAL);
NTQUERYSYSTEMINFORMATION NtQuerySystemInformation = NULL;
NTQUERYINFORMATIONPROCESS NtQueryInformationProcess = NULL;
ULONG g_ulCpuNumber = 0;
std::vector<PROCESS_ITEM_INFORMATION> g_vecSysProInfos;
std::map<HANDLE, HANDLE> g_mapProInfos; //key - UniqueProcessId
PH_UINT64_DELTA g_phCpuCycleDelta = {0};
//查找进程是否已存在上一次保存的进程列表里面
//vecProInfos上一次保存的进程列表
//pProcess当前需要查询的进程
inline BOOL GetProcessInfo(const std::vector<PROCESS_ITEM_INFORMATION> &vecProInfos, ULONG64 ProcessId, ULONG64 CreateTime, PROCESS_ITEM_INFORMATION &itemProcess)
{
BOOL bRet = FALSE;
for (std::vector<PROCESS_ITEM_INFORMATION>::const_iterator iter = vecProInfos.begin(); iter != vecProInfos.end(); ++ iter)
{
PROCESS_ITEM_I