如何获取CPU使用率

        这几天做一个分布式的软件,用到了这些知识,暂时没有时间具体介绍自己的收获和心得,先把代码(转载加修改)贴上吧,以后再补充。

 

一、获取当前进程的CPU使用率、内存使用量、总的IO字节数。

 

ProcessStatus.h

 

#ifndef PROCESS_STATUS_H  
#define PROCESS_STATUS_H  
 
extern "C"
{  
 typedef long long           int64_t;  
 typedef unsigned long long  uint64_t;  

 // Get the CPU usage rate of current process, which fails when the return is -1.
 int get_cpu_usage();  

 // Get the memory usage and virtual memory usage of current process,
 // which fails when the return is -1, otherwise 0 presents success.
 int get_memory_usage(uint64_t* mem, uint64_t* vmem);  

 // Get the total bytes(IO) of read and write of current process,
 // which fails when the return is -1, otherwise 0 presents success.
 int get_io_bytes(uint64_t* read_bytes, uint64_t* write_bytes);
}  
#endif/*PROCESS_STATUS_H*/

 

 

ProcessStatus.cpp

 

#include <windows.h>  
#include <psapi.h>  
#include <assert.h>  
#include "ProcessStatus.h"  

#pragma comment(lib,"psapi.lib")

// Convert time type.  
static uint64_t file_time_2_utc(const FILETIME* ftime)  
{  
 LARGE_INTEGER li;  

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

// Get the core number of the CPU.
static int get_processor_number()  
{  
 SYSTEM_INFO info;  
 GetSystemInfo(&info);  
 return (int)info.dwNumberOfProcessors;  
}  

int get_cpu_usage()  
{  
 // The core number of CPU  
 static int processor_count_ = -1;  
 // The last time  
 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;  

 int cpu = -1;  

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

 GetSystemTimeAsFileTime(&now);  

 if (!GetProcessTimes(GetCurrentProcess(), &creation_time, &exit_time,  
  &kernel_time, &user_time))  
 {  
  // We don't assert here because in some cases (such as in the Task Manager)  
  // we may call this function on a process that has just exited but we have  
  // not yet received the notification.  
  return -1;  
 }  
 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))  
 {  
  // First call, just set the last values.  
  last_system_time_ = system_time;  
  last_time_ = time;  
  return -1;  
 }  

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

 assert(time_delta != 0);  

 if (time_delta == 0)  
  return -1;  

 // We add time_delta / 2 so the result is rounded.  
 cpu = (int)((system_time_delta * 100 + time_delta / 2) / time_delta);  
 last_system_time_ = system_time;  
 last_time_ = time;  
 return cpu;  
}  

 

int get_memory_usage(uint64_t* mem, uint64_t* vmem)  
{  
 PROCESS_MEMORY_COUNTERS pmc;  
 if(GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc)))  
 {  
  if(mem) *mem = pmc.WorkingSetSize;  
  if(vmem) *vmem = pmc.PagefileUsage;  
  return 0;  
 }  
 return -1;  
}  

 

int get_io_bytes(uint64_t* read_bytes, uint64_t* write_bytes)  
{  
 IO_COUNTERS io_counter;  
 if(GetProcessIoCounters(GetCurrentProcess(), &io_counter))  
 {  
  if(read_bytes) *read_bytes = io_counter.ReadTransferCount;  
  if(write_bytes) *write_bytes = io_counter.WriteTransferCount;  
  return 0;  
 }  
 return -1;  

 

 

 

二、获取CPU的使用率

 

Cpusage.cpp

 

#include <windows.h>
#include <conio.h>
#include <stdio.h>

#define SystemBasicInformation       0
#define SystemPerformanceInformation 2
#define SystemTimeInformation        3

 

#define Li2Double(x) ((double)((x).HighPart) * 4.294967296E9 + (double)((x).LowPart))

 

typedef struct
{
    DWORD   dwUnknown1;
    ULONG   uKeMaximumIncrement;
    ULONG   uPageSize;
    ULONG   uMmNumberOfPhysicalPages;
    ULONG   uMmLowestPhysicalPage;
    ULONG   uMmHighestPhysicalPage;
    ULONG   uAllocationGranularity;
    PVOID   pLowestUserAddress;
    PVOID   pMmHighestUserAddress;
    ULONG   uKeActiveProcessors;
    BYTE    bKeNumberProcessors;
    BYTE    bUnknown2;
    WORD    wUnknown3;
} SYSTEM_BASIC_INFORMATION;

typedef struct
{
    LARGE_INTEGER   liIdleTime;
    DWORD           dwSpare[76];
} SYSTEM_PERFORMANCE_INFORMATION;

typedef struct
{
    LARGE_INTEGER liKeBootTime;
    LARGE_INTEGER liKeSystemTime;
    LARGE_INTEGER liExpTimeZoneBias;
    ULONG         uCurrentTimeZoneId;
    DWORD         dwReserved;
} SYSTEM_TIME_INFORMATION;


typedef LONG (WINAPI *PROCNTQSI)(UINT,PVOID,ULONG,PULONG);

PROCNTQSI NtQuerySystemInformation;


void main(void)
{
    SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo;
    SYSTEM_TIME_INFORMATION        SysTimeInfo;
    SYSTEM_BASIC_INFORMATION       SysBaseInfo;
    double                         dbIdleTime;
    double                         dbSystemTime;
    LONG                           status;
    LARGE_INTEGER                  liOldIdleTime = {0,0};
    LARGE_INTEGER                  liOldSystemTime = {0,0};

    NtQuerySystemInformation = (PROCNTQSI)GetProcAddress(
                                          GetModuleHandle("ntdll"),
                                         "NtQuerySystemInformation"
                                         );

    if (!NtQuerySystemInformation)
        return;

    // get number of processors in the system
    status = NtQuerySystemInformation(SystemBasicInformation,&SysBaseInfo,sizeof(SysBaseInfo),NULL);
    if (status != NO_ERROR)
        return;
   
 printf("/nCPU Usage (press any key to exit):    ");
    while(!_kbhit())
    {
        // get new system time
     status = NtQuerySystemInformation(SystemTimeInformation,&SysTimeInfo,sizeof(SysTimeInfo),0);
        if (status!=NO_ERROR)
            return;

        // get new CPU's idle time
        status = NtQuerySystemInformation(SystemPerformanceInformation,&SysPerfInfo,sizeof(SysPerfInfo),NULL);
        if (status != NO_ERROR)
            return;

        // if it's a first call - skip it
       if (liOldIdleTime.QuadPart != 0)
       {
            // CurrentValue = NewValue - OldValue
            dbIdleTime = Li2Double(SysPerfInfo.liIdleTime) - Li2Double(liOldIdleTime);
            dbSystemTime = Li2Double(SysTimeInfo.liKeSystemTime) - Li2Double(liOldSystemTime);

            // CurrentCpuIdle = IdleTime / SystemTime
            dbIdleTime = dbIdleTime / dbSystemTime;

            // CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors
            dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SysBaseInfo.bKeNumberProcessors + 0.5;

            printf("/b/b/b/b%3d%%",(UINT)dbIdleTime);
       }

        // store new CPU's idle and system time
        liOldIdleTime = SysPerfInfo.liIdleTime;
        liOldSystemTime = SysTimeInfo.liKeSystemTime;
  
        // wait one second
        Sleep(1000);
    }
    printf("/n");
}

在 Windows 系统中,可以通过多种方式获取 CPU 使用率,其中较为常见的方式是使用 Windows API 函数,例如 `GetSystemTimes` 或 `Pdh` 相关接口来实现。以下将介绍这两种方式的具体实现方法。 ### 使用 `GetSystemTimes` 获取 CPU 使用率 `GetSystemTimes` 函数可以获取系统空闲时间、用户模式时间和内核模式时间。通过记录两个时间点的差异,可以计算出 CPU使用率。以下是一个使用 `GetSystemTimes` 获取 CPU 使用率的示例代码: ```c #include <windows.h> #include <stdio.h> typedef struct { FILETIME idleTime; FILETIME kernelTime; FILETIME userTime; } CpuUsageData; double CalculateCpuUsage(FILETIME* previous, FILETIME* current) { ULARGE_INTEGER prev, curr; prev.LowPart = previous->dwLowDateTime; prev.HighPart = previous->dwHighDateTime; curr.LowPart = current->dwLowDateTime; curr.HighPart = current->dwHighDateTime; ULONGLONG diff = curr.QuadPart - prev.QuadPart; LARGE_INTEGER freq; QueryPerformanceFrequency(&freq); return ((double)diff / (double)freq.QuadPart) * 100.0; } void GetCpuUsageUsingSystemTimes() { CpuUsageData data1, data2; if (!GetSystemTimes(&data1.idleTime, &data1.kernelTime, &data1.userTime)) { printf("Failed to get system times.\n"); return; } Sleep(1000); // 等待1秒 if (!GetSystemTimes(&data2.idleTime, &data2.kernelTime, &data2.userTime)) { printf("Failed to get system times.\n"); return; } double kernelUsage = CalculateCpuUsage(&data1.kernelTime, &data2.kernelTime); double userUsage = CalculateCpuUsage(&data1.userTime, &data2.userTime); printf("CPU Usage: %.2f%%\n", kernelUsage + userUsage); } ``` ### 使用 `Pdh` 获取 CPU 使用率 `Pdh`(Performance Data Helper)是 Windows 提供的一组 API,用于访问性能计数器。通过 `Pdh` 接口可以更方便地获取系统级别的 CPU 使用率。以下是一个使用 `Pdh` 获取 CPU 使用率的示例代码: ```cpp #include <windows.h> #include <pdh.h> #include <pdhmsg.h> #include <stdio.h> #pragma comment(lib, "pdh.lib") int GetCpuUsageUsingPdh() { PDH_HQUERY query; PDH_HCOUNTER counter; PDH_FMT_COUNTERVALUE counterValue; PdhOpenQuery(NULL, 0, &query); PdhAddCounter(query, L"\\Processor(_Total)\\% Processor Time", 0, &counter); PdhCollectQueryData(query); Sleep(1000); // 等待1秒 PdhCollectQueryData(query); PdhGetFormattedCounterValue(counter, PDH_FMT_DOUBLE, NULL, &counterValue); printf("CPU Usage: %.2f%%\n", counterValue.doubleValue); PdhCloseQuery(query); return 0; } ``` ### 整合与对比 两种方法各有优劣。`GetSystemTimes` 更加底层,适用于需要直接访问系统时间的场景,但需要手动计算 CPU 使用率;而 `Pdh` 提供了更高层次的封装,能够更方便地获取 CPU 使用率,但依赖于性能计数器的支持。根据具体需求,可以选择合适的方式来获取 CPU 使用率。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值