简体   繁体   English

每个进程的CPU使用率

[英]CPU Usage of every process

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. 我在Google上找到了这段代码,该代码计算了win10当前进程使用率的百分比,但是我正在寻找的是每个进程的CPU使用率百分比的列表。 I use GetCurrentProcess() to have the handle of the current process. 我使用GetCurrentProcess()获取当前进程的句柄。 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. 然后,我需要计算每个人的cpu使用率,但我在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?

ok, for effective coding this task need use NtQueryInformationProcess with SystemProcessInformation info class. 好的,为了有效编码,此任务需要将NtQueryInformationProcessSystemProcessInformation info类一起使用。 we got here array of SYSTEM_PROCESS_INFORMATION . 我们在这里得到了SYSTEM_PROCESS_INFORMATION数组。 here we already have: 这里我们已经有:

LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;

when in PROCESSENTRY32 no this members. PROCESSENTRY32没有此成员。 toolhelp functions simply drop this member. toolhelp函数只是删除该成员。 without it we need open every process, call GetProcessTimes , etc. with NtQueryInformationProcess all become much more effective and simply. 没有它,我们需要打开每个进程,使用NtQueryInformationProcess调用GetProcessTimes等,所有这些都将变得更加有效和简单。 general idea - we need maintain list of processes, and periodic call NtQueryInformationProcess for add new created processes and remove died. 一般思想-我们需要维护进程列表,并定期调用NtQueryInformationProcess来添加新创建的进程并删除已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);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM