C++统计单个进程的CPU占用率、内存占用率

2,135 阅读2分钟

C++统计单个进程的CPU占用率、内存占用率

最近在写一个Flutter PC 段项目,有一个需求就是统计当前进程CPU占用率。但是Flutter并没有提供内丝的API、只能用C++混编了、C++比较蹩脚的我也是费了很大的功夫才整理出来的,希望对你有帮助 代码注释应该还算比较友好、主要内容如下:

C++统计单个进程的CPU占用率、单个进程的内存占用率。和整个电脑当前内存占用率和CPU占用率的方法。

代码如下。需要自提

JCInstrument.h

#include <Windows.h>
#include <Psapi.h>
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <windows.h>  
#include <psapi.h>  
#include <thread>
#include <string>

using namespace std;

int GetCurrentPid(); // 获取当前进程 pid

double getPidMemory(DWORD processID); // 根据pid获取 占用内存大小

double get_cpu_usage_pid(int pid); // 根据pid 获取  CPU占用率

double get_mem_usage();  // 获取当前内存总使用率

double get_all_memory(); // 获取总共的虚拟内存

double get_cpu_usage();  // 获取当前 CPU 总使用率

string doubleToString(long double value); // double to String

JCInstrument.cpp

#include "JCInstrument.h"

using namespace std;


// 获取当前Pid
int GetCurrentPid()
{
    return _getpid();
}

// 获取指定 pid 占用内存大小
double getPidMemory(DWORD processID)
{
    HANDLE hProcess;
    PROCESS_MEMORY_COUNTERS pmc;
    double workingSize = 0.0;
    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
        PROCESS_VM_READ,
        FALSE, processID);
    if (NULL == hProcess)
        return 0.0;

    if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc)))
    {
        workingSize = pmc.WorkingSetSize / 1024.0 / 1024.0;
    }

    CloseHandle(hProcess);
    return workingSize;
}

// 获取总内存占用率
double get_mem_usage()
{
    MEMORYSTATUS ms;
    ::GlobalMemoryStatus(&ms);
    return ms.dwMemoryLoad;
}

// 获取计算机虚拟内存
double get_all_memory()
{
    MEMORYSTATUSEX statex;
    statex.dwLength = sizeof(statex);
    GlobalMemoryStatusEx(&statex);
    DWORDLONG physical_memory = statex.ullTotalPhys / (1024 * 1024);
    return physical_memory;
}

__int64 JCCompareFileTime(FILETIME time1, FILETIME time2)
{
    __int64 a = time1.dwHighDateTime << 32 | time1.dwLowDateTime;
    __int64 b = time2.dwHighDateTime << 32 | time2.dwLowDateTime;
    return   (b - a);
}

// 获取总CPU使用率
double get_cpu_usage()
{
    HANDLE hEvent;
    BOOL res;

    FILETIME preidleTime;
    FILETIME prekernelTime;
    FILETIME preuserTime;

    FILETIME idleTime;
    FILETIME kernelTime;
    FILETIME userTime;

    res = GetSystemTimes(&idleTime, &kernelTime, &userTime);

    preidleTime = idleTime;
    prekernelTime = kernelTime;
    preuserTime = userTime;

    hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); // 初始值为 nonsignaled ,并且每次触发后自动设置为nonsignaled

    int a = 0;
    int cpu = 0;
    int cpuidle = 0;
    while (a < 3) {

        WaitForSingleObject(hEvent, 1000); //等待500毫秒
        res = GetSystemTimes(&idleTime, &kernelTime, &userTime);

        int idle = JCCompareFileTime(preidleTime, idleTime);
        int kernel = JCCompareFileTime(prekernelTime, kernelTime);
        int user = JCCompareFileTime(preuserTime, userTime);

        cpu = (kernel + user - idle) * 100 / (kernel + user);
        cpuidle = (idle) * 100 / (kernel + user);

        preidleTime = idleTime;
        prekernelTime = kernelTime;
        preuserTime = userTime;
        a++;
    }

    return cpuidle;
}

/// time convert
static uint64_t file_time_2_utc(const FILETIME* ftime)
{
    LARGE_INTEGER li;

    li.LowPart = ftime->dwLowDateTime;
    li.HighPart = ftime->dwHighDateTime;
    return li.QuadPart;
}

// get CPU num
static int get_processor_number()
{
    SYSTEM_INFO info;
    GetSystemInfo(&info);
    return (int)info.dwNumberOfProcessors;
}


// 获取 单个进程 CPU 占用率
double get_cpu_usage_pid(int pid)
{
    static int processor_count_ = -1;
    static int64_t last_time_ = 0;
    static int64_t last_system_time_ = 0;

    FILETIME now;
    FILETIME creation_time;
    FILETIME exit_time;
    FILETIME kernel_time;
    FILETIME user_time;
    int64_t system_time;
    int64_t time;
    int64_t system_time_delta;
    int64_t time_delta;

    double cpu = -1;

    if (processor_count_ == -1)
    {
        processor_count_ = get_processor_number();
    }

    GetSystemTimeAsFileTime(&now);

    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
    if (!GetProcessTimes(hProcess, &creation_time, &exit_time, &kernel_time, &user_time))
    {
        return 0.0;
    }
    system_time = (file_time_2_utc(&kernel_time) + file_time_2_utc(&user_time)) / processor_count_;
    time = file_time_2_utc(&now);

    if ((last_system_time_ == 0) || (last_time_ == 0))
    {
        last_system_time_ = system_time;
        last_time_ = time;
        return get_cpu_usage_pid(pid);
    }

    system_time_delta = system_time - last_system_time_;
    time_delta = time - last_time_;

    if (time_delta == 0)
    {
        return get_cpu_usage_pid(pid);
    }

    cpu = (double)(system_time_delta * 100.0 / time_delta);
    last_system_time_ = system_time;
    last_time_ = time;
    return cpu;
}

string doubleToString(long double value)
{
    std::string str;
    char tmp[12345];
    sprintf_s(tmp, "%.2f", value);
    str.assign(tmp);
    return str;
}

test.cpp

#include "JCIstrument.h"
#include <iostream>
#include <string>

using namespace std;

int main()
{
    cout << "hellow word" << endl;
     
    int pid = 10924;

    cout << pid << endl;

    double memory = getPidMemory(pid);

    double allMemory = get_all_memory();

    double memoryRate = memory / allMemory;

    cout << "当前内存占用" << memory << endl;

    cout << "总内存" << allMemory << endl;

    cout << "当前进程内存占用率" << memoryRate << endl;

    string rate = doubleToString(memoryRate);

    cout << "当前进程内存占用率" << rate << endl;

    while (true)
    {
        Sleep(1000);

        double cpuRate = get_cpu_usage_pid(pid);

        cout << "当前进程CPU占用率" << cpuRate << endl;
    }

    system("pause");

    return 0;
}

刚入门C++、写的不好。大家将就看看吧~ 有不妥之处欢迎指出。