簡體   English   中英

每個進程的CPU使用率

[英]CPU Usage of every process

我在Google上找到了這段代碼,該代碼計算了win10當前進程使用率的百分比,但是我正在尋找的是每個進程的CPU使用率百分比的列表。 我使用GetCurrentProcess()獲取當前進程的句柄。 有沒有辦法檢索每個進程的句柄?我正在編寫列出正在運行的進程並計算每個人的使用內存的代碼。 然后,我需要計算每個人的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?

好的,為了有效編碼,此任務需要將NtQueryInformationProcessSystemProcessInformation info類一起使用。 我們在這里得到了SYSTEM_PROCESS_INFORMATION數組。 這里我們已經有:

LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;

PROCESSENTRY32沒有此成員。 toolhelp函數只是刪除該成員。 沒有它,我們需要打開每個進程,使用NtQueryInformationProcess調用GetProcessTimes等,所有這些都將變得更加有效和簡單。 一般思想-我們需要維護進程列表,並定期調用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