zoukankan      html  css  js  c++  java
  • 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的任务管理器基本上没有什么大的差别,但未对百分比数据进行修订,以使得数据位数达到一致!

  • 相关阅读:
    〖Linux〗Kubuntu设置打开应用时就只在打开时的工作区显示
    〖Linux〗Kubuntu, the application 'Google Chrome' has requested to open the wallet 'kdewallet'解决方法
    unity, dll is not allowed to be included or could not be found
    android check box 自定义图片
    unity, ios skin crash
    unity, Collider2D.bounds的一个坑
    unity, ContentSizeFitter立即生效
    类里的通用成员函数应声明为static
    unity, Gizmos.DrawMesh一个坑
    直线切割凹多边形
  • 原文地址:https://www.cnblogs.com/ubunoon/p/System_Information_CPU_Rate.html
Copyright © 2011-2022 走看看