我在google上发现了这个代码,用于计算win10上当前进程的使用百分比,但我要查找的是每个进程的CPU使用百分比列表。 我使用GetCurrentProcess()来获得当前进程的句柄。有没有办法检索每个进程的句柄?我正在编写一个列出运行进程的代码,并为每个人计算使用内存。然后我需要计算每个人的CPU使用率,但我没有在谷歌上找到任何东西。
static ULARGE_INTEGER lastCPU, lastSysCPU, lastUserCPU;
static int numProcessors;
static HANDLE self;
void init(){
SYSTEM_INFO sysInfo;
FILETIME ftime, fsys, fuser;
GetSystemInfo(&sysInfo);
numProcessors = sysInfo.dwNumberOfProcessors;
GetSystemTimeAsFileTime(&ftime);
memcpy(&lastCPU, &ftime, sizeof(FILETIME));
self = GetCurrentProcess();
GetProcessTimes(self, &ftime, &ftime, &fsys, &fuser);
memcpy(&lastSysCPU, &fsys, sizeof(FILETIME));
memcpy(&lastUserCPU, &fuser, sizeof(FILETIME));
}
double getCurrentValue(){
FILETIME ftime, fsys, fuser;
ULARGE_INTEGER now, sys, user;
long double percent;
GetSystemTimeAsFileTime(&ftime);
memcpy(&now, &ftime, sizeof(FILETIME));
GetProcessTimes(GetCurrentProcess(), &ftime, &ftime, &fsys, &fuser);
memcpy(&sys, &fsys, sizeof(FILETIME));
memcpy(&user, &fuser, sizeof(FILETIME));
percent = (sys.QuadPart - lastSysCPU.QuadPart) +
(user.QuadPart - lastUserCPU.QuadPart);
percent /= (now.QuadPart - lastCPU.QuadPart);
percent /= numProcessors;
lastCPU = now;
lastUserCPU = user;
lastSysCPU = sys;
return percent * 100;
}
I'm able to have the list of all running processes but i'm looking for to
calculate cpu usage for every process.
Suggestions?
答案 0 :(得分:1)
好的,要有效编码此任务,需要将NtQueryInformationProcess
与SystemProcessInformation
信息类一起使用。我们在这里获得SYSTEM_PROCESS_INFORMATION
数组。我们已经在这里:
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
在PROCESSENTRY32
时没有这个成员。 toolhelp函数只是删除此成员。如果没有它,我们需要打开每个流程,使用NtQueryInformationProcess
调用GetProcessTimes
等等都会变得更加有效和简单。一般的想法 - 我们需要维护进程列表,并定期调用NtQueryInformationProcess
以添加新创建的进程并删除死亡。
// for debug only 0 <= cpuUsage <= 1000
void PrintCpuUsage(ULONG cpuUsage, PCUNICODE_STRING Name)
{
ULONG p = cpuUsage / 10;
DbgPrint("%02u.%u %wZ\n", p, cpuUsage - p * 10, Name);
}
struct PROCESS_ENTRY : LIST_ENTRY, UNICODE_STRING
{
LARGE_INTEGER _CreateTime, _RunTime;
union {
LARGE_INTEGER _Delta;
ULONG _cpuUsage;
};
HANDLE _UniqueProcessId;
HANDLE _InheritedFromUniqueProcessId;
BOOLEAN _bEnumerated;
PROCESS_ENTRY()
{
RtlInitUnicodeString(this, 0);
InitializeListHead(this);
_RunTime.QuadPart = 0;
_UniqueProcessId = 0;
}
~PROCESS_ENTRY()
{
DbgPrint("--%08x(%08x) %wZ\n", _UniqueProcessId, _InheritedFromUniqueProcessId, static_cast<UNICODE_STRING*>(this));
RtlFreeUnicodeString(this);
RemoveEntryList(this);
}
NTSTATUS Init(PSYSTEM_PROCESS_INFORMATION pspi)
{
_UniqueProcessId = pspi->UniqueProcessId;
_InheritedFromUniqueProcessId = pspi->InheritedFromUniqueProcessId;
_CreateTime = pspi->CreateTime;
DbgPrint("++%08x(%08x) %wZ\n", _UniqueProcessId, _InheritedFromUniqueProcessId, &pspi->ImageName);
return RtlDuplicateUnicodeString(RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE, &pspi->ImageName, this);
}
LONGLONG UpdateProcess(PSYSTEM_PROCESS_INFORMATION pspi)
{
_bEnumerated = TRUE;
pspi->KernelTime.QuadPart += pspi->UserTime.QuadPart;
_Delta.QuadPart = pspi->KernelTime.QuadPart - _RunTime.QuadPart;
_RunTime.QuadPart = pspi->KernelTime.QuadPart;
return _Delta.QuadPart;
}
void CalcCpuUsage(LONGLONG QuadPart)
{
_bEnumerated = FALSE;
_cpuUsage = (ULONG)((_Delta.QuadPart * 1000) / QuadPart );
if (_cpuUsage && _UniqueProcessId)
{
PrintCpuUsage(_cpuUsage, this);
}
}
};
struct PROCES_LIST : public LIST_ENTRY
{
LIST_ENTRY _ListHead;
PROCESS_ENTRY IdleProcess;
BOOL _bValid;
PROCES_LIST()
{
InitializeListHead(&_ListHead);
_bValid = FALSE;
}
LONGLONG UpdateOrAddNewProcess(PSYSTEM_PROCESS_INFORMATION pspi);
void RemoveDiedEntries(LONGLONG QuadPart);
void EnumPro();
~PROCES_LIST()
{
RemoveDiedEntries(0);
}
};
LONGLONG PROCES_LIST::UpdateOrAddNewProcess(PSYSTEM_PROCESS_INFORMATION pspi)
{
PROCESS_ENTRY* pe;
PLIST_ENTRY head = &_ListHead, entry = head;
HANDLE UniqueProcessId = pspi->UniqueProcessId;
while ((entry = entry->Flink) != head)
{
pe = static_cast<PROCESS_ENTRY*>(entry);
if (pe->_UniqueProcessId == UniqueProcessId && pe->_CreateTime.QuadPart == pspi->CreateTime.QuadPart)
{
return pe->UpdateProcess(pspi);
}
}
if (pe = new PROCESS_ENTRY)
{
if (0 <= pe->Init(pspi))
{
InsertTailList(head, pe);
return pe->UpdateProcess(pspi);
}
delete pe;
}
return 0;
}
void PROCES_LIST::RemoveDiedEntries(LONGLONG QuadPart)
{
PLIST_ENTRY head = &_ListHead, entry = head->Flink;
while (entry != head)
{
PROCESS_ENTRY* pe = static_cast<PROCESS_ENTRY*>(entry);
entry = entry->Flink;
if (pe->_bEnumerated)
{
pe->CalcCpuUsage(QuadPart);
}
else
{
delete pe;
}
}
}
void PROCES_LIST::EnumPro()
{
ULONG cb = 0, rcb = 0x10000;
PVOID stack = alloca(guz);// volatile UCHAR guz;
union {
PVOID buf;
PBYTE pb;
PSYSTEM_PROCESS_INFORMATION pspi;
};
NTSTATUS status;
do
{
if (cb < rcb)
{
cb = RtlPointerToOffset(buf = alloca(rcb - cb), stack);
}
if (0 <= (status = NtQuerySystemInformation(SystemProcessInformation, buf, cb, &rcb)))
{
LONGLONG QuadPart = 0;
ULONG NextEntryOffset = 0;
do
{
pb += NextEntryOffset;
if (pspi->UniqueProcessId)
{
QuadPart += UpdateOrAddNewProcess(pspi);
}
else
{
QuadPart += IdleProcess.UpdateProcess(pspi);
}
} while (NextEntryOffset = pspi->NextEntryOffset);
RemoveDiedEntries(QuadPart);
IdleProcess.CalcCpuUsage(QuadPart);
if (_bValid)
{
static UNICODE_STRING empty;
PrintCpuUsage(1000 - IdleProcess._cpuUsage, &empty);
}
else
{
_bValid = TRUE;
}
}
} while (status == STATUS_INFO_LENGTH_MISMATCH);
}