Windows 下获取多核CPU使用率

Windows 下获取多核CPU使用率

该方法使用于NT内核的windows系统,windows2000以后的版本都适用。NT下利用ntdll.dll中没有公开的API: NtQuerySystemInformation,文档参考:http://msdn.microsoft.com/en-us/library/ms724509.aspx

扩展参考参考:
MSDN
讲解如何利用NT Native API获取NT系统的CPU使用率(支持多核)
Win32 SDK 获得多核心处理器使用率。
阅读更多查看代码
代码一: 产生CPU曲线,源自《编程之美》第一章
#include <windows.h>
#include <stdlib.h>
#include <math.h>
const int SAMPLING_COUNT = 200;
const double PI = 3.1415926535;
const int TOTAL_AMPLITUDE = 600;
 
int main(int argc, char* argv[])
{
    DWORD busySpan[SAMPLING_COUNT];
    int amplitude = TOTAL_AMPLITUDE / 2;
 
    double radian = 0.0;
 
    double radianIncrement = 2.0 / (double) SAMPLING_COUNT;
 
    for (int i = 0; i< SAMPLING_COUNT; i++)
    {
        busySpan[i] = (DWORD) (amplitude + (sin(PI * radian) * amplitude));
        radian += radianIncrement;
    }
 
    DWORD startTime = 0;
 
    for (int j = 0;; j = (j+1) % SAMPLING_COUNT)
    {
        startTime = GetTickCount();
        while ((GetTickCount() - startTime ) <= busySpan[j])
            ;
        Sleep(TOTAL_AMPLITUDE - busySpan[j]);
    }
    return 0;
}
代码二: 获取CPU使用率

#include <windows.h>
#include <stdio.h>
 
#define SystemBasicInformation 0
#define SystemPerformanceInformation 2
#define SystemTimeInformation 3
#define SystemProcessorPerformanceInformation 8
 
#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 struct
_SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION {
    LARGE_INTEGER IdleTime;
    LARGE_INTEGER KernelTime;
    LARGE_INTEGER UserTime;
    LARGE_INTEGER DpcTime;
    LARGE_INTEGER InterruptTime;
    ULONG Reserved2;
} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION;
 
typedef struct
_m_PROCESSORS_USE_TIME {
    double dbOldIdleTime;    // save old total time
    double dbOldCurrentTime;
    double dbIdleTime;        // save time after calc
    double dbCurrentTime;
    float fUse;
}m_PROCESSORS_USE_TIME;
 
m_PROCESSORS_USE_TIME * m_PUT;
 
SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION * m_pSPPI = NULL;
 
int m_iNumberProcessors;
 
typedef LONG (WINAPI *PROCNTQSI)(UINT,PVOID,ULONG,PULONG);
 
PROCNTQSI NtQuerySystemInformation;
 
static LARGE_INTEGER liOldIdleTime = {0,0};
static LARGE_INTEGER liOldSystemTime = {0,0};
 
double dbIdleTime = 0;
double dbSystemTime = 0;
double alldbIdleTime = 0;
 
void init()
{
}
 
int GetCpuUsage()
{
    SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo;
    SYSTEM_TIME_INFORMATION SysTimeInfo;
    SYSTEM_BASIC_INFORMATION SysBaseInfo;
 
    LONG status;
 
    NtQuerySystemInformation = (PROCNTQSI)GetProcAddress(GetModuleHandle("ntdll"),"NtQuerySystemInformation");
    // get number of processors in the system
    status = NtQuerySystemInformation(SystemBasicInformation,&SysBaseInfo,sizeof(SysBaseInfo),NULL);
    if (status != NO_ERROR)
        return -1;
 
    if (!NtQuerySystemInformation)
        return -1;
 
    // get number of processors in the system
    status = NtQuerySystemInformation(SystemBasicInformation,&SysBaseInfo,sizeof(SysBaseInfo),NULL);
    if (status != NO_ERROR)
        return -1;
 
    // get new system time
    status = NtQuerySystemInformation(SystemTimeInformation,&SysTimeInfo,sizeof(SysTimeInfo),0);
    if (status!=NO_ERROR)
        return -1;
 
    // get new CPU's idle time
    status =NtQuerySystemInformation(SystemPerformanceInformation,&SysPerfInfo,sizeof(SysPerfInfo),NULL);
    if (status != NO_ERROR)
        return -1;
 
    if ( m_iNumberProcessors != SysBaseInfo.bKeNumberProcessors)
    {
        //save
        m_iNumberProcessors = SysBaseInfo.bKeNumberProcessors;
        //if sppi not null clear
        if (m_pSPPI != NULL) delete []m_pSPPI;
        if (m_PUT != NULL) delete []m_PUT;
        //malloc and point
        m_pSPPI = new SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION[m_iNumberProcessors];
        m_PUT = new m_PROCESSORS_USE_TIME[m_iNumberProcessors];
    }
 
    // get ProcessorPer time
    status =NtQuerySystemInformation(SystemProcessorPerformanceInformation, m_pSPPI, sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * m_iNumberProcessors, NULL);
    if (status != NO_ERROR)
        return -1;
 
    // 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;
 
        //calc Processors
        for (int i = 0; i < m_iNumberProcessors; i++)
        {
            m_PUT[i].dbCurrentTime = Li2Double(m_pSPPI[i].KernelTime) + Li2Double(m_pSPPI[i].UserTime) +
                                        Li2Double(m_pSPPI[i].DpcTime) + Li2Double(m_pSPPI[i].InterruptTime) - m_PUT[i].dbOldCurrentTime;
            m_PUT[i].dbIdleTime = Li2Double(m_pSPPI[i].IdleTime) - m_PUT[i].dbOldIdleTime;
 
            // CurrentCpuIdle = IdleTime / SystemTime
            m_PUT[i].dbIdleTime = m_PUT[i].dbIdleTime / m_PUT[i].dbCurrentTime;
 
            // CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors
            m_PUT[i].dbIdleTime = 100.0 - m_PUT[i].dbIdleTime * 100.0 + 0.5;
        }
    }
 
    // store new CPU's idle and system time
    liOldIdleTime = SysPerfInfo.liIdleTime;
    liOldSystemTime = SysTimeInfo.liKeSystemTime;
 
    for (int i = 0; i < m_iNumberProcessors; i++)
    {
        m_PUT[i].dbOldCurrentTime = Li2Double(m_pSPPI[i].KernelTime) + Li2Double(m_pSPPI[i].UserTime) +
                                        Li2Double(m_pSPPI[i].DpcTime) + Li2Double(m_pSPPI[i].InterruptTime);
        m_PUT[i].dbOldIdleTime = Li2Double(m_pSPPI[i].IdleTime);
    }
    return (int)dbIdleTime;
}
 
int main()
{
    init();
 
    while( !_kbhit ( ))
    {
        printf("%3d%%", GetCpuUsage());
        printf("%d", m_iNumberProcessors);
 
        for (int i = 0; i < m_iNumberProcessors; i++)
        {
            printf(" %.0f%%", m_PUT[i].dbIdleTime);
        }
        printf("\n");
    /*    printf(" %.0f, %.0f |", m_PUT[0].dbIdleTime, m_PUT[0].dbCurrentTime);
        printf(" %.0f, %.0f |", m_PUT[1].dbIdleTime, m_PUT[1].dbCurrentTime);
        printf(" %.0f, %.0f |", m_PUT[2].dbIdleTime, m_PUT[2].dbCurrentTime);
        printf(" %.0f, %.0f |\n", m_PUT[3].dbIdleTime, m_PUT[3].dbCurrentTime);*/
 
        Sleep(1000);
    }
    return 0;
}
 
     


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值