• CPU占用率


    下面是头文件
    /************************************************************************/
    /* 
    * 作者:cpp
    * 日期:2008-09-05
    * 内容:提供了一个CSystemInformation类,该类可以获取CPU厂家,
    *                CPU频率,CPU个数,当前使用的CPU,系统运行时占用的
    *                CPU比率,系统运行的Idle时间,User时间以及Kernel时间
    *                获取某个进程的句柄个数,获取随机数(比编译器自带更灵活),
    *                以及将长整数(long long )转换为浮点数,宽字节与窄字节之间的互换
    *
    * 注意:有几个函数仅可以用在windows xp系统上,在其他系统上将失效或不起作用
    *                因此,调用时需要注意,另外,如果转入到其他编译器_WIN32_WINNT用来
    *                指示需要windows xp系统
    */

    /************************************************************************/

    #pragma once

    #include
    <sstream>
    #include 
    <cassert>

    #ifndef _WINBASE_
    #include 
    <WinBase.h>
    #endif // _WINBASE_H

    //#define  _WIN32_WINNT // 该值已经在stdafx.h中被声明过,只能够用在winxp系统上

    typedef 
    struct _SYSTEM_BASIC_INFORMATION {
        BYTE Reserved1[
    24];
        PVOID Reserved2[
    4];
        CCHAR NumberOfProcessors;
    }
     SYSTEM_BASIC_INFORMATION;  // 结构等同于SYSTEM_INFO

    typedef 
    struct
    {
        
    long long             IdleTime;
        DWORD           dwReversed[
    76];
    }
     SYSTEM_PERFORMANCE_INFORMATION;

    typedef 
    struct _SYSTEM_PROCESS_INFORMATION {
        ULONG NextEntryOffset;
        BYTE Reserved1[
    52];
        PVOID Reserved2[
    3];
        HANDLE UniqueProcessId;
        PVOID Reserved3;
        ULONG HandleCount;
        BYTE Reserved4[
    4];
        PVOID Reserved5[
    11];
        SIZE_T PeakPagefileUsage;
        SIZE_T PrivatePageCount;
        LARGE_INTEGER Reserved6[
    6];
    }
     SYSTEM_PROCESS_INFORMATION;

    typedef 
    struct
    {
        LARGE_INTEGER liKeBootTime;
        LARGE_INTEGER liKeSystemTime;
        LARGE_INTEGER liExpTimeZoneBias;
        ULONG         uCurrentTimeZoneId;
        DWORD         dwReserved;
    }
     SYSTEM_TIME_INFORMATION;  // 等同于GetSystemTimes获取到的三个数据

    class CSystemInformation
    {
    public:
    // 定义基础数据类型
        typedef std::basic_string<TCHAR> string;
        typedef std::basic_stringstream
    <TCHAR> stringstream;
        typedef std::basic_string
    <BYTE>  byteString;

    public:
        
    enum SYSTEM_INFORMATION
        
    {
            SystemBasicInformation 
    = 0,
            SystemPerformanceInformation 
    = 2,
            SystemTimeInformation  
    = 3,
        }
    ;
    protected:
        typedef DWORD (WINAPI
    * NTQUERYSYSTEMINFOMATION) (         
            SYSTEM_INFORMATION SystemInformationClass,
            PVOID SystemInformation,
            ULONG SystemInformationLength,
            PULONG ReturnLength );

    public:
        CSystemInformation(
    void);
    public:
        
    ~CSystemInformation(void);
    public:
        
    // 获取基础信息系统,并返回处理
        const LPSYSTEM_INFO GetSystemInfo(void);

    protected:
        
    // 处理错误消息
        void ProcessErrorMessage(TCHAR* ErrorText);
    public:
        
    // 产生给定长度的随机数,由windows系统产生,比C编译器产生的更加随机
        byteString GenRandom(int len);

    public:
        
    // 返回转换后的wchar_t指针,并返回长度
        wchar_t* ToChar(const char* str, int* len);
    public:
        
    // 返回转换后的char指针,并返回长度
        char* ToChar(const wchar_t* str, int* len);
    public:
        
    // 获取本地机器的CPU硬件信息
        string GetCPUCompany(void);
    public:
        
    // 获取CPU个数
        int GetCPUNumbers(void);
    public:
        
    // 获取当前CPU编号-即当前使用的是哪个CPU
        int GetCurrentCPU(void);
    public:
        
    // 获取某个打开进程的句柄个数
        long GetProcessHandleCount(HANDLE hProcess);
    public:
        
    // 获取系统空闲时间
        LPFILETIME GetIdleTime(void);

    public:
        
    // 获取系统核心运行时间
        LPFILETIME GetKernelTime(void);
        
    // 获取用户运行时间
        LPFILETIME GetUserTime(void);
    public:
        
    // 获取系统(空闲,核心以及用户)运行时间
        void GetSystemTimes(LPFILETIME IdleTime, LPFILETIME KernelTime, LPFILETIME UserTime,  bool ImmediateRet=false);
    public:
        
    // 获取CPU占用率
        double GetCPURate(void);
    public:
        
    // 将64位的长整数转换为64位的实数
        double LongInt2Double(LARGE_INTEGER want);
    public:
        
    double LongInt2Double(long long want)
        
    {
            LARGE_INTEGER _want;
            memcpy( 
    &_want, &want, sizeof(LARGE_INTEGER) );
            
    return LongInt2Double(  _want );
        }

        
    double LongInt2Double(FILETIME want)
        
    {        
            LARGE_INTEGER _want;
            memcpy( 
    &_want, &want, sizeof(LARGE_INTEGER) );
            
    return LongInt2Double( _want);
        }

    public:
        
    // 获取CPU的频率,高字节部分为主频,低字节部分为次频,以GHz为单位
        int GetCPUFrenquence(void);
    public:
        
    // 获取当前使用的CPU编号
        int GetCurrentUseCPU(void);

    public:
        
    // 获取注册表所能够达到的最大尺寸,以字节为单位
        long GetMaxRegisterSize(void);
    public:
        
    // 获取当前注册表的尺寸,以字节为单位
        long GetCurrRegisterSize(void);

    private:
        
    long long  m_IdleTime;
        
    long long m_KernelTime;
        
    long long  m_UserTime;
        
    // 用来表示是否已经获取了系统的信息,true为已经获取,false为没有获取
        bool m_bHasSystemInfo;
        wchar_t    
    *m_pWChar;
        
    char    *m_pchar;
    private:
        
    // 系统信息
        SYSTEM_INFO m_system_info;
    private:
        
    // NTDLL.DLL 句柄
        HMODULE m_hNtDll;
        
    // NtQuerySystemInformation 函数地址
        NTQUERYSYSTEMINFOMATION NtQuerySystemInformation; 
    }
    ;
    下面是实现文件:
     
    /************************************************************************/
    /* 
    * 作者:cpp
    * 日期:2008-09-05
    * 内容:提供了一个CSystemInformation类,该类可以获取CPU厂家,
    *                CPU频率,CPU个数,当前使用的CPU,系统运行时占用的
    *                CPU比率,系统运行的Idle时间,User时间以及Kernel时间
    *                获取某个进程的句柄个数,获取随机数(比编译器自带更灵活),
    *                将长整数(long long )转换为浮点数,宽字节与窄字节之间的互换
    *                注册表最大容量,当前注册表容量
    */

    /************************************************************************/

    //#include "stdafx.h"
    #include <windows.h>
    #include 
    "SystemInformation.h"
    #include 
    <WinCrypt.h>
    #include 
    <winbase.h>

    CSystemInformation::CSystemInformation()
    : m_bHasSystemInfo(
    false)
    {
        m_pWChar 
    = NULL;
        m_pchar 
    = NULL;
        m_hNtDll 
    = NULL;

        m_bHasSystemInfo 
    = false;

        ::memset( 
    &m_system_info, 0sizeof(m_system_info));

        m_hNtDll 
    = ::LoadLibrary(TEXT("ntdll.dll"));
        
    if( NULL == m_hNtDll)
        
    {
            
    this->ProcessErrorMessage(TEXT("没有载入ntdll.dll文件!"));
            
    return ;
        }

        
    this->NtQuerySystemInformation = (NTQUERYSYSTEMINFOMATION) GetProcAddress(
                m_hNtDll, 
    "NtQuerySystemInformation"
            );
        
    if( NULL== NtQuerySystemInformation )
        
    {
            
    this->ProcessErrorMessage(TEXT("没有找到NtQuerySystemInformation地址!"));
            
    return ;
        }

        
    }


    CSystemInformation::
    ~CSystemInformation()
    {
        
    if( NULL != m_pWChar)
        
    {
            delete []m_pWChar;
            m_pWChar 
    = NULL;
        }


        
    if( NULL != m_pchar )
        
    {
            delete []m_pchar;
            m_pchar 
    = NULL;
        }

        
        
    if( NULL != m_hNtDll )
        
    {
            FreeLibrary(m_hNtDll);
            m_hNtDll 
    = NULL;
        }


    }


    void CSystemInformation::ProcessErrorMessage( TCHAR* ErrorText )
    {
        LPVOID lpMsgBuf;

        FormatMessage( 
            FORMAT_MESSAGE_ALLOCATE_BUFFER 
    | FORMAT_MESSAGE_FROM_SYSTEM,
            NULL,
            GetLastError(),
            MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), 
    // Default language
            (LPTSTR) &lpMsgBuf,
            
    0,
            NULL 
            );
        stringstream ss;
        ss 
    << TEXT("警告:"<< ErrorText << TEXT("存在下面的错误:\n")
            
    << lpMsgBuf << std::endl;
        MessageBox(NULL, ss.str().c_str(), TEXT(
    "程序错误"), MB_ICONSTOP);
        LocalFree(lpMsgBuf);
    }


    const LPSYSTEM_INFO CSystemInformation::GetSystemInfo( void )
    {
        ::GetSystemInfo( 
    &m_system_info );
        m_bHasSystemInfo 
    = true;
        
    return &m_system_info;
    }


    CSystemInformation::byteString CSystemInformation::GenRandom( 
    int len )
    {
        HCRYPTPROV hCryptProc;
        TCHAR
    *     UserName = TEXT("MyKeyContainer");
        
    if! CryptAcquireContext(&hCryptProc, UserName, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET ) )
        
    {
            ProcessErrorMessage(TEXT(
    "没有得到加密锁!"));
            
    return byteString();
        }


        byteString bstr;
        
    try
        
    {
            BYTE 
    *pbBuffer = new BYTE[len];
            
    if!CryptGenRandom( hCryptProc, len, pbBuffer) )
            
    {
                ProcessErrorMessage(TEXT(
    "没有产生得到随机数!"));
            }

            bstr 
    = pbBuffer;
        }
    catch()
        
    {
            ProcessErrorMessage(TEXT(
    "GenRandom--没有足够内存!"));
        }

        CryptReleaseContext(hCryptProc,
    0);
        
    return bstr;
    }


    wchar_t
    * CSystemInformation::ToChar( const char* str, int* len )
    {
        
    int strLen = strlen(str);
        
    try
        
    {
            
    if ( NULL != m_pWChar)
            
    {
                
    ifsizeof(m_pWChar)/sizeof(m_pWChar[0]) < strLen+1 )
                
    {
                    delete[] m_pWChar;
                    m_pWChar 
    = new wchar_t[strLen+1 ];
                }

            }
     
            
    else
            
    {
                    m_pWChar 
    = new wchar_t[strLen+1 ];
            }

            
    *len = strLen + 1;
        }

        
    catch()
        
    {
            ProcessErrorMessage(TEXT(
    "没有足够内存!"));
            
    *len = 0;
        }

        
    return m_pWChar;
    }


    char* CSystemInformation::ToChar( const wchar_t* str, int* len )
    {
        
    int wStrLen = ::wcslen(str);
        
    try
        
    {
            
    if ( sizeof(m_pchar)/sizeof(m_pchar[0]) < wStrLen+1 )
            
    {
                delete [] m_pchar;
                m_pchar 
    = new char [ wStrLen+1];
            }
     
            
    else
            
    {
                m_pchar 
    = new char [ wStrLen+1];
            }

            
    *len = wStrLen;        
        }

        
    catch()
        
    {
            ProcessErrorMessage(TEXT(
    "没有足够内存!"));
            
    *len = 0;
        }


        
    return m_pchar;
    }

    // 获取本地机器的CPU类型
    CSystemInformation::string CSystemInformation::GetCPUCompany( void )
    {
        
    if! m_bHasSystemInfo )
            
    this->GetSystemInfo();

        WORD processor 
    = HIWORD( m_system_info.dwOemId );

        stringstream ss;
        
    switch ( processor )
        
    {
        
    case PROCESSOR_ARCHITECTURE_INTEL:
            ss 
    << TEXT("Intel CPU")   ; 
                
    break;
        
    case PROCESSOR_ARCHITECTURE_AMD64:
                ss 
    <<TEXT("Amd64 CPU") ;
                
    break;
        
    case PROCESSOR_ARCHITECTURE_ARM:
                ss 
    <<TEXT("Arm CPU")  ;            
                
    break;
        
    case PROCESSOR_ARCHITECTURE_ALPHA:
                ss 
    <<TEXT("Alpha CPU") ;        
                
    break;
        
    case PROCESSOR_ARCHITECTURE_IA64:
                ss 
    <<TEXT("IA64 CPU") ;
                
    break;
        
    default:
                ss 
    <<  TEXT("unknown CPU") ;
                
    break;
        }

        
    return ss.str();
    }


    // 获取CPU个数
    int CSystemInformation::GetCPUNumbers(void)
    {
        
    if!m_bHasSystemInfo )
            
    this->GetSystemInfo();

        
    return m_system_info.dwNumberOfProcessors;
    }


    // 获取当前CPU编号-即当前使用的是哪个CPU
    // 系统最多支持32个CPU
    int CSystemInformation::GetCurrentCPU(void)
    {
        
    if!m_bHasSystemInfo )
            
    this->GetSystemInfo();

        
    int current_cpu = 1;
        
    for(int i=0; i< 32; i++)
        
    {
            
    if( m_system_info.dwActiveProcessorMask & ( 1<<i) )
            
    {
                current_cpu 
    = i;
                
    break;
            }

        }

        
    return current_cpu+1;
    }


    // 获取某个打开进程的句柄个数
    long CSystemInformation::GetProcessHandleCount(HANDLE hProcess)
    {
        DWORD dwProcessCount 
    = 0;

    /*    if( !::GetProcessHandleCount(hProcess,&dwProcessCount) )
        {
            ProcessErrorMessage(TEXT("获取进程内句柄个数失败!"));
            dwProcessCount = 0;
        }
    */

        
    return dwProcessCount;
    }


    // 获取系统空闲时间
    LPFILETIME CSystemInformation::GetIdleTime(void)
    {
    /*
        if( !::GetSystemTimes((LPFILETIME)&m_IdleTime,(LPFILETIME) &m_KernelTime, (LPFILETIME)&m_UserTime))
        {
                ProcessErrorMessage(TEXT("获取系统运行时间错误!"));
        }
    */

        
    return (LPFILETIME)&m_IdleTime;
    }


    // 获取系统核心运行时间
    LPFILETIME CSystemInformation::GetKernelTime(void)
    {
    /*
        if(! ::GetSystemTimes((LPFILETIME)&m_IdleTime,(LPFILETIME) &m_KernelTime, (LPFILETIME)&m_UserTime))
        {
                ProcessErrorMessage(TEXT("获取系统运行时间错误!"));
        }
    */

        
    return (LPFILETIME)&m_KernelTime;
    }


    // 获取用户运行时间
    LPFILETIME CSystemInformation::GetUserTime(void)
    {
      
    /*
        if( ! ::GetSystemTimes((LPFILETIME)&m_IdleTime, (LPFILETIME)&m_KernelTime, (LPFILETIME)&m_UserTime) )
        {
                ProcessErrorMessage(TEXT("获取系统运行时间错误!"));
        }
      
    */

        
    return (LPFILETIME)&m_UserTime;
    }



    // 同时获取获取系统(空闲,核心以及用户)运行时间
    void CSystemInformation::GetSystemTimes(LPFILETIME IdleTime, LPFILETIME KernelTime, LPFILETIME UserTime, bool ImmediateRet /*=false*/)
    {
    /*
        if( ! ::GetSystemTimes( IdleTime, KernelTime, UserTime) )
        {
                ProcessErrorMessage(TEXT("获取系统运行时间错误!"));
        }
    */

        
    if( ImmediateRet )
            
    return ;

        memcpy( 
    &m_IdleTime, IdleTime, sizeof( FILETIME) );
        memcpy( 
    &m_KernelTime, KernelTime, sizeof( FILETIME) );
        memcpy( 
    &m_UserTime, UserTime, sizeof(FILETIME) );

    }


    // 获取CPU占用率
    double CSystemInformation::GetCPURate(void)
    {
        SYSTEM_PERFORMANCE_INFORMATION  SysPerfInfo;
        SYSTEM_TIME_INFORMATION        SysTimeInfo;
        SYSTEM_BASIC_INFORMATION       SysBaseInfo;

        
    double IdleTime = 0 ;
        
    static double OldIdleTime = 0;   
        
    double SystemTime = 0;
        
    static double OldSystemTime = 0;

        
    if( NtQuerySystemInformation )
        
    {
            DWORD status 
    = NtQuerySystemInformation(SystemBasicInformation, &SysBaseInfo, 
                    
    sizeof(SYSTEM_BASIC_INFORMATION), NULL);
            
    //GetSystemInfo();

            
    if ( NO_ERROR != status)
            
    {
                ProcessErrorMessage(TEXT(
    "没有获取到系统基础信息!"));
                
    return 0;
            }


            
    //GetIdleTime();    // 获取系统的三个时间
            status = NtQuerySystemInformation(SystemTimeInformation, &SysTimeInfo,
            
    sizeof(SYSTEM_TIME_INFORMATION), NULL);
            
    if ( NO_ERROR != status)
            
    {
                ProcessErrorMessage(TEXT(
    "没有获取到系统基础信息!"));
                
    return 0;
            }


            status 
    = NtQuerySystemInformation(SystemPerformanceInformation, &SysPerfInfo, 
                            
    sizeof(SYSTEM_PERFORMANCE_INFORMATION), NULL);
            
    if ( NO_ERROR != status)
            
    {
                    ProcessErrorMessage(TEXT(
    "没有获取到系统基础信息!"));
                    
    return 0;
            }


            
    if ( 0 != OldIdleTime )
            
    {
                IdleTime 
    = LongInt2Double(SysPerfInfo.IdleTime)  - OldIdleTime;
                SystemTime 
    = LongInt2Double(SysTimeInfo.liKeSystemTime) - OldSystemTime;
                
    // 采用这种方式获取的CPU占用率,获取的值与任务管理相差较大
                
    //SystemTime = LongInt2Double(m_KernelTime) - OldSystemTime; 
                IdleTime = IdleTime/SystemTime;
                
                IdleTime 
    = 100 -  IdleTime*100.0/(double)SysBaseInfo.NumberOfProcessors;
            }

            OldIdleTime 
    = LongInt2Double(SysPerfInfo.IdleTime);
            OldSystemTime 
    =LongInt2Double( SysTimeInfo.liKeSystemTime );
            
    //OldSystemTime = LongInt2Double(m_KernelTime);
            
    //Sleep(100);
        }

        
    return IdleTime;
    }


    // 将64位的长整数转换为64位的实数
    double CSystemInformation::LongInt2Double(LARGE_INTEGER want)
    {
        
    return ((double)(want.HighPart) * 4.294967296E9 + (double)(want.LowPart) );
    }



    // 获取CPU的频率,高word部分为主频,低word部分为次频,以GHz为单位
    int CSystemInformation::GetCPUFrenquence(void)
    {
        
    if ( !m_bHasSystemInfo )
        
    {
            
    this->GetSystemInfo();
        }

    /************************************************************************
    #ifdef _DEBUG
        stringstream ss;
        ss << HIBYTE(m_system_info.wProcessorRevision) <<LOBYTE(m_system_info.wProcessorRevision) << std::endl;
        AfxMessageBox( ss.str().c_str() );
    #endif // _DEBUG
    */

        
    return m_system_info.wProcessorRevision;
    }


    // 获取注册表所能够达到的最大尺寸,以字节为单位
    long CSystemInformation::GetMaxRegisterSize(void)
    {
        unsigned 
    long Max = 0;
        unsigned 
    long Curr = 0;
    /*    if ( !GetSystemRegistryQuota(&Max, &Curr) )
        {
            ProcessErrorMessage(TEXT("没有获取到系统的注册表存储容量信息!"));
            return 0;
        }
    */

        
    return Max;
    }


    // 获取当前注册表的尺寸,以字节为单位
    long CSystemInformation::GetCurrRegisterSize(void)
    {
        unsigned 
    long Max = 0;
        unsigned 
    long Curr = 0;
    /*
        if ( !GetSystemRegistryQuota(&Max, &Curr) )
        {
            ProcessErrorMessage(TEXT("没有获取到系统的注册表存储容量信息!"));
            return 0;
        }
    */

        
    return Curr;    
    }


    需要注意的是,其中还有部分成员函数不能够良好工作,但CPU占用率已经可以非常良好的运行,与windows的任务管理器基本上没有什么大的差别,但未对百分比数据进行修订,以使得数据位数达到一致!

  • 相关阅读:
    jq获取滚动条高度
    用jq实现简单的tab选项卡
    bootstrap基础css样式1
    c3中的弹性盒子
    第一天注册
    Windows平台下结合 tortoiseSVN 和 VisualSVN Server 搭建SVN服务器并实现 web 站点同步
    【转载】IIS出现“HTTP 错误 500.0,C:phpphp-cgi.exe
    【转载】PHP5.3 配置文件php.ini-development和php.ini-production的区别
    解决 Composer-Setup.exe 安装过程中的报错
    IIS配置页面重写(配合插件url-rewrite2去除页面后缀名)
  • 原文地址:https://www.cnblogs.com/ubunoon/p/System_Information_CPU_Rate.html
Copyright © 2020-2023  润新知