每个进程的CPU使用率 [英] CPU Usage of every process

查看:167
本文介绍了每个进程的CPU使用率的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Google上找到了这段代码,该代码计算了win10当前进程使用率的百分比,但是我要查找的是每个进程的CPU使用率百分比的列表。
我使用GetCurrentProcess()获取当前进程的句柄。有没有办法检索每个进程的句柄?我正在编写列出正在运行的进程并计算每个人的使用内存的代码。然后我需要计算每个人的cpu使用率,但我在Google上找不到任何内容。

I found this code on google that calculate of % of usage of current process on win10,but what i'm looking for is a list of % of CPU Usage of every process. I use GetCurrentProcess() to have the handle of the current process. Is there a way to retrieve the handle of every processes?i'm working on a code that lists running process and calculate usage memory for everyone. Then i need to calculate cpu usage for everyone but i didn't find anything on google.

    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?


推荐答案

好的,为有效编码,此任务需要使用 NtQueryInformationProcess SystemProcessInformation 信息类。我们在这里找到了 SYSTEM_PROCESS_INFORMATION 。在这里我们已经有了:

ok, for effective coding this task need use NtQueryInformationProcess with SystemProcessInformation info class. we got here array of SYSTEM_PROCESS_INFORMATION. here we already have:

LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;

PROCESSENTRY32 尚无此成员。 toolhelp函数只是删除该成员。如果没有它,我们需要打开每个进程,使用GetProcessTimes 等。 rel = nofollow noreferrer> NtQueryInformationProcess 变得更加有效和简单。一般想法-我们需要维护进程列表,并定期调用 NtQueryInformationProcess 用于添加新创建的进程并删除已终止。

when in PROCESSENTRY32 no this members. toolhelp functions simply drop this member. without it we need open every process, call GetProcessTimes, etc. with NtQueryInformationProcess all become much more effective and simply. general idea - we need maintain list of processes, and periodic call NtQueryInformationProcess for add new created processes and remove died.

// 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);
}

这篇关于每个进程的CPU使用率的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆