欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

通過(guò)C++獲取CPU占用率的代碼示例(windows、linux、macOS)

 更新時(shí)間:2025年03月10日 08:52:38   作者:鄭天佐  
本文介紹了在Windows、Linux和macOS平臺(tái)下使用C++獲取CPU占用率的多種方法,包括系統(tǒng)整體CPU占用率和特定進(jìn)程CPU占用率的計(jì)算公式和實(shí)現(xiàn)代碼示例,需要的朋友可以參考下

獲取CPU占用率

windows平臺(tái)

在Windows系統(tǒng)下使用C++獲取CPU占用率,常見(jiàn)方法可分為系統(tǒng)整體占用率和特定進(jìn)程占用率兩類(lèi)。以下是具體實(shí)現(xiàn)方法及核心代碼示例:

一、獲取系統(tǒng)整體CPU占用率

方法1:基于GetSystemTimes函數(shù)

原理:通過(guò)計(jì)算兩次采樣的系統(tǒng)空閑時(shí)間、內(nèi)核時(shí)間和用戶時(shí)間差值,結(jié)合公式得出整體CPU使用率。

#include <windows.h>
#include <iostream>

double GetCpuUsage() {
    FILETIME idleTime, kernelTime, userTime;
    static FILETIME preIdleTime, preKernelTime, preUserTime;

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

    // 轉(zhuǎn)換為64位整型
    ULONGLONG idle = (*(ULONGLONG*)&idleTime) - (*(ULONGLONG*)&preIdleTime);
    ULONGLONG kernel = (*(ULONGLONG*)&kernelTime) - (*(ULONGLONG*)&preKernelTime);
    ULONGLONG user = (*(ULONGLONG*)&userTime) - (*(ULONGLONG*)&preUserTime);

    preIdleTime = idleTime;
    preKernelTime = kernelTime;
    preUserTime = userTime;

    if (kernel + user == 0) return 0.0;
    return ((kernel + user - idle) * 100.0) / (kernel + user);
}

// 調(diào)用示例
int main() {
    while (true) {
        Sleep(1000); // 間隔1秒采樣
        std::cout << "CPU Usage: " << GetCpuUsage() << "%" << std::endl;
    }
    return 0;
}
  • 關(guān)鍵點(diǎn):
    需間隔一定時(shí)間(如1秒)采樣兩次數(shù)據(jù)。
    公式:(內(nèi)核時(shí)間 + 用戶時(shí)間 - 空閑時(shí)間) / (內(nèi)核時(shí)間 + 用戶時(shí)間)。

方法2:使用性能計(jì)數(shù)器(PDH庫(kù))

適用場(chǎng)景:需要高精度或?qū)崟r(shí)監(jiān)控多個(gè)計(jì)數(shù)器。

#include <windows.h>
#include <pdh.h>
#pragma comment(lib, "pdh.lib") 

double GetCpuUsageByPdh() {
    static PDH_HQUERY query;
    static PDH_HCOUNTER counter;
    static bool initialized = false;
    
    if (!initialized) {
        PdhOpenQuery(nullptr, 0, &query);
        PdhAddCounter(query, L"\\Processor(_Total)\\% Processor Time", 0, &counter);
        initialized = true;
    }

    PDH_FMT_COUNTERVALUE value;
    PdhCollectQueryData(query);
    PdhGetFormattedCounterValue(counter, PDH_FMT_DOUBLE, nullptr, &value);
    return value.doubleValue; 
}
  • 優(yōu)點(diǎn):與任務(wù)管理器數(shù)據(jù)一致,支持多核統(tǒng)計(jì)。

二、獲取特定進(jìn)程CPU占用率

原理:通過(guò)GetProcessTimes獲取進(jìn)程的內(nèi)核和用戶時(shí)間,計(jì)算兩次采樣的時(shí)間差占比。

#include <windows.h>
#include <iostream>

class ProcessCpuMonitor {
public:
    ProcessCpuMonitor(DWORD pid) : pid_(pid) {
        hProcess_ = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid_);
    }

    ~ProcessCpuMonitor() {
        if (hProcess_) CloseHandle(hProcess_);
    }

    float GetUsage() {
        FILETIME createTime, exitTime, kernelTime, userTime;
        if (!GetProcessTimes(hProcess_, &createTime, &exitTime, &kernelTime, &userTime))
            return -1;

        ULONGLONG currentKernel = *(ULONGLONG*)&kernelTime;
        ULONGLONG currentUser = *(ULONGLONG*)&userTime;
        ULONGLONG delta = (currentKernel + currentUser) - (lastKernel_ + lastUser_);

        // 計(jì)算時(shí)間差(單位:100納秒)
        ULONGLONG timePassed = GetTickCount64() - lastTick_;
        lastTick_ = GetTickCount64();
        lastKernel_ = currentKernel;
        lastUser_ = currentUser;

        if (timePassed == 0) return 0.0f;
        return (delta / 10000.0f) / timePassed * 100.0f; // 轉(zhuǎn)換為百分比
    }

private:
    DWORD pid_;
    HANDLE hProcess_ = nullptr;
    ULONGLONG lastKernel_ = 0, lastUser_ = 0;
    ULONGLONG lastTick_ = 0;
};

// 調(diào)用示例
int main() {
    DWORD pid = 1234; // 目標(biāo)進(jìn)程ID
    ProcessCpuMonitor monitor(pid);
    while (true) {
        Sleep(1000);
        std::cout << "Process CPU Usage: " << monitor.GetUsage() << "%" << std::endl;
    }
    return 0;
}

注意事項(xiàng):

需以PROCESS_QUERY_LIMITED_INFORMATION權(quán)限打開(kāi)進(jìn)程。
公式:(進(jìn)程時(shí)間差 / 系統(tǒng)時(shí)間差) * 100%。

三、常見(jiàn)問(wèn)題

  • 與任務(wù)管理器數(shù)據(jù)不一致:因采樣間隔和計(jì)算方式差異,結(jié)果可能有輕微偏差。
  • 多核CPU:上述方法返回的是整體利用率,如需單核數(shù)據(jù),需遍歷每個(gè)邏輯處理器。
  • 權(quán)限問(wèn)題:獲取系統(tǒng)級(jí)數(shù)據(jù)需管理員權(quán)限,進(jìn)程級(jí)數(shù)據(jù)則不需要。

linux平臺(tái)

在Linux系統(tǒng)下使用C++獲取CPU占用率,主要通過(guò)解析/proc/stat文件實(shí)現(xiàn)。以下是具體實(shí)現(xiàn)方法和原理說(shuō)明:

一、核心原理

Linux內(nèi)核通過(guò)/proc/stat文件提供CPU活動(dòng)的統(tǒng)計(jì)信息。文件中記錄了從系統(tǒng)啟動(dòng)到當(dāng)前時(shí)刻,CPU在不同狀態(tài)下的累計(jì)時(shí)間(單位:時(shí)鐘周期),包括:

  • user:用戶態(tài)執(zhí)行時(shí)間
  • nice:低優(yōu)先級(jí)用戶態(tài)時(shí)間
  • system:內(nèi)核態(tài)執(zhí)行時(shí)間
  • idle:空閑時(shí)間
  • iowait:I/O等待時(shí)間
  • irq:硬件中斷時(shí)間
  • softirq:軟件中斷時(shí)間

通過(guò)兩次采樣這些數(shù)值,計(jì)算時(shí)間差并分析CPU占用率。

二、實(shí)現(xiàn)步驟

讀取 /proc/stat 文件

#include <fstream>
#include <vector>
#include <string>

struct CpuTime {
    unsigned long user, nice, system, idle, iowait, irq, softirq;
};

CpuTime readCpuStats() {
    std::ifstream file("/proc/stat");
    std::string cpu_label;
    CpuTime time;
    file >> cpu_label >> time.user  >> time.nice  >> time.system  >> time.idle  
         >> time.iowait  >> time.irq  >> time.softirq; 
    return time;
}
  • 計(jì)算CPU使用率
    通過(guò)兩次采樣時(shí)間差計(jì)算CPU利用率:
double calculateCpuUsage(const CpuTime& prev, const CpuTime& curr) {
    const unsigned long prev_total = prev.user  + prev.nice  + prev.system  + prev.idle  
                                   + prev.iowait  + prev.irq  + prev.softirq; 
    const unsigned long curr_total = curr.user  + curr.nice  + curr.system  + curr.idle  
                                   + curr.iowait  + curr.irq  + curr.softirq; 
    const unsigned long total_diff = curr_total - prev_total;

    const unsigned long idle_diff = curr.idle  - prev.idle; 
    return (total_diff - idle_diff) * 100.0 / total_diff;
}
  • 完整示例
#include <iostream>
#include <unistd.h>

int main() {
    CpuTime prev = readCpuStats();
    sleep(1); // 采樣間隔1秒
    CpuTime curr = readCpuStats();
    
    double usage = calculateCpuUsage(prev, curr);
    std::cout << "CPU Usage: " << usage << "%" << std::endl;
    return 0;
}

三、擴(kuò)展說(shuō)明

多核CPU處理
/proc/stat中每行對(duì)應(yīng)一個(gè)CPU核心(如cpu0, cpu1),需分別解析。

進(jìn)程級(jí)CPU占用率
通過(guò)讀取/proc/[pid]/stat獲取進(jìn)程的utime(用戶態(tài)時(shí)間)和stime(內(nèi)核態(tài)時(shí)間),結(jié)合系統(tǒng)總時(shí)間計(jì)算。

注意事項(xiàng)
采樣間隔建議≥1秒,避免瞬時(shí)波動(dòng)。
需處理/proc文件讀取失敗的情況。
高精度場(chǎng)景可使用clock_gettime替代sleep。

四、優(yōu)化與替代方案

使用 sysinfo 系統(tǒng)調(diào)用
獲取粗略的系統(tǒng)負(fù)載信息,但精度較低。

調(diào)用 getrusage 函數(shù)
適用于統(tǒng)計(jì)進(jìn)程自身的CPU使用情況。

第三方庫(kù)
如libstatgrab或procps-ng提供封裝接口。

macOS平臺(tái)

在 macOS 系統(tǒng)下通過(guò) C++ 獲取 CPU 占用率,需要調(diào)用 Mach 內(nèi)核 API 實(shí)現(xiàn)。以下是基于 、、 等資料的實(shí)現(xiàn)方案:

一、核心實(shí)現(xiàn)原理

Mach API 調(diào)用
macOS 基于 Darwin 內(nèi)核,通過(guò) <mach/mach_host.h> 提供的 host_statistics 函數(shù)獲取 CPU 時(shí)間統(tǒng)計(jì)信息。

CPU 占用率計(jì)算
需兩次采樣間隔內(nèi)的 CPU 使用時(shí)間差,公式:
CPU 占用率 = (用戶態(tài)時(shí)間 + 內(nèi)核態(tài)時(shí)間) / (總時(shí)間差) * 100%

二、代碼實(shí)現(xiàn)示例

#include <mach/mach_host.h>
#include <mach/processor_info.h>
#include <unistd.h>

double get_cpu_usage() {
    host_cpu_load_info_data_t cpuinfo;
    mach_msg_type_number_t count = HOST_CPU_LOAD_INFO_COUNT;
    kern_return_t kr = host_statistics(mach_host_self(), 
                                      HOST_CPU_LOAD_INFO,
                                      (host_info_t)&cpuinfo,
                                      &count);
    if (kr != KERN_SUCCESS) return -1.0;

    // 第一次采樣
    uint64_t total_user_prev = cpuinfo.cpu_ticks[CPU_STATE_USER]; 
    uint64_t total_sys_prev = cpuinfo.cpu_ticks[CPU_STATE_SYSTEM]; 
    uint64_t total_idle_prev = cpuinfo.cpu_ticks[CPU_STATE_IDLE]; 
    uint64_t total_used_prev = total_user_prev + total_sys_prev;

    // 等待 1 秒后再次采樣
    sleep(1);
    kr = host_statistics(mach_host_self(),
                        HOST_CPU_LOAD_INFO,
                        (host_info_t)&cpuinfo,
                        &count);
    if (kr != KERN_SUCCESS) return -1.0;

    uint64_t total_user = cpuinfo.cpu_ticks[CPU_STATE_USER]; 
    uint64_t total_sys = cpuinfo.cpu_ticks[CPU_STATE_SYSTEM]; 
    uint64_t total_idle = cpuinfo.cpu_ticks[CPU_STATE_IDLE]; 
    uint64_t total_used = total_user + total_sys;

    // 計(jì)算差值
    uint64_t used_diff = total_used - total_used_prev;
    uint64_t idle_diff = total_idle - total_idle_prev;
    uint64_t total_diff = used_diff + idle_diff;

    return (total_diff == 0) ? 0 : (used_diff * 100.0) / total_diff;
}

三、關(guān)鍵點(diǎn)說(shuō)明

多核 CPU 處理
上述代碼返回的是 所有 CPU 核心的平均占用率。若需獲取單核數(shù)據(jù),需通過(guò) host_processor_info 函數(shù)遍歷每個(gè)核心 。

時(shí)間間隔選擇
兩次采樣間隔建議 1 秒(sleep(1)),間隔過(guò)短會(huì)導(dǎo)致誤差增大。

錯(cuò)誤處理
檢查 host_statistics 返回值是否為 KERN_SUCCESS,避免因權(quán)限問(wèn)題或 API 調(diào)用失敗導(dǎo)致崩潰。

四、擴(kuò)展功能

獲取單進(jìn)程 CPU 占用
結(jié)合 proc_pidinfo 函數(shù)和 PROC_PIDTASKINFO 參數(shù),可獲取指定進(jìn)程的 CPU 時(shí)間 。

實(shí)時(shí)監(jiān)控
通過(guò)多線程循環(huán)調(diào)用上述函數(shù),實(shí)現(xiàn)動(dòng)態(tài)曲線繪制(參考 中的 ImGui 方案)。

五、編譯注意事項(xiàng)

頭文件依賴:需包含 <mach/mach.h> 和 <mach/mach_host.h>

鏈接框架:添加 -framework IOKit 編譯選項(xiàng)

示例:clang++ -framework IOKit cpu_usage.cpp -o cpu_usage

以上就是通過(guò)C++獲取CPU占用率的代碼示例(windows、linux、macOS)的詳細(xì)內(nèi)容,更多關(guān)于C++獲取CPU占用率的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Qt自定義控件實(shí)現(xiàn)進(jìn)度儀表盤(pán)

    Qt自定義控件實(shí)現(xiàn)進(jìn)度儀表盤(pán)

    這篇文章主要介紹了Qt自定義控件實(shí)現(xiàn)進(jìn)度儀表盤(pán),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-12-12
  • C語(yǔ)言編程遞歸算法實(shí)現(xiàn)漢諾塔

    C語(yǔ)言編程遞歸算法實(shí)現(xiàn)漢諾塔

    遞歸,大家都了解,著名的斐波那契數(shù),就為該知識(shí)點(diǎn)的經(jīng)典例題。今天來(lái)看看更為經(jīng)典的遞歸題漢諾塔不過(guò)這其實(shí)是數(shù)學(xué)問(wèn)題,先來(lái)看看漢諾塔
    2021-09-09
  • C++ 內(nèi)存分配處理函數(shù)set_new_handler的使用

    C++ 內(nèi)存分配處理函數(shù)set_new_handler的使用

    這篇文章主要介紹了C++ 內(nèi)存分配處理函數(shù)set_new_handler的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • C語(yǔ)言 TerminateProcess函數(shù)案例詳解

    C語(yǔ)言 TerminateProcess函數(shù)案例詳解

    這篇文章主要介紹了C語(yǔ)言 TerminateProcess函數(shù)案例詳解,本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • Qt?http編程之nlohmann?json庫(kù)使用詳解

    Qt?http編程之nlohmann?json庫(kù)使用詳解

    nlohmann是一個(gè)C++的JSON庫(kù),它提供了方便的方式來(lái)解析、生成和操作JSON數(shù)據(jù),這篇文章主要為大家介紹了nlohmann?json庫(kù)的簡(jiǎn)單使用,希望對(duì)大家有所幫助
    2024-04-04
  • C語(yǔ)言關(guān)于時(shí)間復(fù)雜度詳解

    C語(yǔ)言關(guān)于時(shí)間復(fù)雜度詳解

    大家好,本篇文章主要講的是C語(yǔ)言關(guān)于時(shí)間復(fù)雜度詳解,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽
    2022-01-01
  • Qt實(shí)現(xiàn)可拖動(dòng)按鈕

    Qt實(shí)現(xiàn)可拖動(dòng)按鈕

    這篇文章主要為大家詳細(xì)介紹了Qt實(shí)現(xiàn)可拖動(dòng)按鈕,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-08-08
  • C語(yǔ)言中帶頭雙向循環(huán)鏈表基本操作的實(shí)現(xiàn)詳解

    C語(yǔ)言中帶頭雙向循環(huán)鏈表基本操作的實(shí)現(xiàn)詳解

    無(wú)頭單向非循環(huán)鏈表結(jié)構(gòu)簡(jiǎn)單,一般不會(huì)單獨(dú)用來(lái)存數(shù)據(jù)。而帶頭雙向循環(huán)鏈表的結(jié)構(gòu)較為復(fù)雜,一般用在單獨(dú)存儲(chǔ)數(shù)據(jù)。本文將介紹帶頭雙向循環(huán)鏈表的基本操作,需要的可以參考一下
    2022-11-11
  • Qt串口通信開(kāi)發(fā)之QSerialPort模塊詳細(xì)使用方法與實(shí)例

    Qt串口通信開(kāi)發(fā)之QSerialPort模塊詳細(xì)使用方法與實(shí)例

    這篇文章主要介紹了Qt串口通信開(kāi)發(fā)之QSerialPort模塊詳細(xì)使用方法與實(shí)例,需要的朋友可以參考下
    2020-03-03
  • C/C++讀取大文件數(shù)據(jù)方式詳細(xì)講解

    C/C++讀取大文件數(shù)據(jù)方式詳細(xì)講解

    這篇文章主要介紹了C語(yǔ)言/C++讀取大文件數(shù)據(jù)的完整方式過(guò)程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-09-09

最新評(píng)論