Windows 方案:PDH (Performance Data Helper)
#include
#pragma comment(lib, "pdh.lib")
double GetCpuUsage() {
PDH_HQUERY query;
PDH_HCOUNTER counter;
PdhOpenQuery(NULL, 0, &query);
PdhAddEnglishCounter(query, "\\Processor(_Total)\\% Processor Time", 0, &counter);
PdhCollectQueryData(query);
Sleep(1000); // 採樣間隔
PdhCollectQueryData(query);
PDH_FMT_COUNTERVALUE value;
PdhGetFormattedCounterValue(counter, PDH_FMT_DOUBLE, NULL, &value);
PdhCloseQuery(query);
return value.doubleValue;
}
Linux 方案:解析 /proc/stat
#include
#include
#include
#include
#include
double GetCpuUsageLinux() {
auto readCpuTimes = []() {
std::ifstream f("/proc/stat");
std::string line;
std::getline(f, line); // cpu 123 45 67 ...
std::istringstream iss(line.substr(5));
long val; std::vector times;
while (iss >> val) times.push_back(val);
return times; // user, nice, system, idle, iowait, irq, softirq, steal, guest, guest_nice
};
auto t1 = readCpuTimes();
std::this_thread::sleep_for(std::chrono::milliseconds(500));
auto t2 = readCpuTimes();
long idle1 = t1[3], total1 = 0; for (auto v : t1) total1 += v;
long idle2 = t2[3], total2 = 0; for (auto v : t2) total2 += v;
return 100.0 * (1.0 - double(idle2 - idle1) / (total2 - total1));
}
跨平台封裝建議
class CpuMonitor {
public:
static double GetUsage() {
#if defined(_WIN32)
return GetCpuUsageWin();
#elif defined(__linux__)
return GetCpuUsageLinux();
#else
return -1.0;
#endif
}
};
注意事項
- Windows 需鏈接
pdh.lib,且首次調用需預熱一次。
- Linux 容器環境下
/proc/stat 反映宿主機 CPU,若需容器限額請讀 /sys/fs/cgroup/cpu/cpu.stat。
- 多核心邏輯 CPU 使用率已包含在總值中,如需單核請解析
cpu0, cpu1... 行。