获取进程对应的CPU使用率

来源:互联网 发布:c语言mp3播放器源代码 编辑:程序博客网 时间:2024/06/02 07:59

//这是头文件cpu.h==================

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

#define STATUS_INFO_LENGTH_MISMATCH      ((NTSTATUS)0xC0000004)
typedef LONG NTSTATUS;
#define Li2Double(x) ((double)((x).HighPart) * 4.294967296E9 + (double)((x).LowPart))

//self def struct.
typedef struct CpuData
{
 DWORD dwPID;
 UINT cpuusage;
 __int64  lastidle;
 __int64  lastsys;
 LARGE_INTEGER  qCputime;
 LARGE_INTEGER  qKernelTime;
 LARGE_INTEGER  qUserTime;
} *pCpuData;

typedef struct _SYSTEM_PERFORMANCE_INFORMATION
{
 LARGE_INTEGER IdleTime;          //CPU空闲时间; 
 LARGE_INTEGER ReadTransferCount;     //I/O读操作数目; 
 LARGE_INTEGER WriteTransferCount;     //I/O写操作数目; 
 LARGE_INTEGER OtherTransferCount;     //I/O其他操作数目; 
 ULONG     ReadOperationCount;     //I/O读数据数目; 
 ULONG     WriteOperationCount;     //I/O写数据数目; 
 ULONG     OtherOperationCount;     //I/O其他操作数据数目; 
 ULONG     AvailablePages;       //可获得的页数目; 
 ULONG     TotalCommittedPages;     //总共提交页数目; 
 ULONG     TotalCommitLimit;      //已提交页数目; 
 ULONG     PeakCommitment;       //页提交峰值; 
 ULONG     PageFaults;         //页故障数目; 
 ULONG     WriteCopyFaults;       //Copy-On-Write故障数目; 
 ULONG     TransitionFaults;      //软页故障数目; 
 ULONG     CacheTransitionFaults; //================= 
 ULONG     DemandZeroFaults;      //需求0故障数; 
 ULONG     PagesRead;         //读页数目; 
 ULONG     PageReadIos;         //读页I/O操作数; 
 ULONG     CacheReadFaults; 
 ULONG     CacheIoFaults; 
 ULONG     PagefilePagesWritten;    //已写页文件页数; 
 ULONG     PagefilePageWriteIos;    //已写页文件操作数; 
 ULONG     MappedFilePagesWritten;   //已写映射文件页数; 
 ULONG     MappedFileWriteIos;     //已写映射文件操作数; 
 ULONG     PagedPoolUsage;       //分页池使用; 
 ULONG     NonPagedPoolUsage;     //非分页池使用; 
 ULONG     PagedPoolAllocs;       //分页池分配情况; 
 ULONG     PagedPoolFrees;       //分页池释放情况; 
 ULONG     NonPagedPoolAllocs;     //非分页池分配情况; 
 ULONG     NonPagedPoolFress;     //非分页池释放情况; 
 ULONG     TotalFreeSystemPtes;     //系统页表项释放总数; 
 ULONG     SystemCodePage;       //操作系统代码页数; 
 ULONG     TotalSystemDriverPages;   //可分页驱动程序页数; 
 ULONG     TotalSystemCodePages;    //操作系统代码页总数; 
 ULONG     SmallNonPagedLookasideListAllocateHits; //小非分页侧视列表分配次数; 
 ULONG     SmallPagedLookasideListAllocateHits;  //小分页侧视列表分配次数; 
 ULONG     Reserved3;         
 ULONG     MmSystemCachePage;     //系统缓存页数; 
 ULONG     PagedPoolPage;       //分页池页数; 
 ULONG     SystemDriverPage;     //可分页驱动页数; 
 ULONG     FastReadNoWait;       //异步快速读数目; 
 ULONG     FastReadWait;       //同步快速读数目; 
 ULONG     FastReadResourceMiss;   //快速读资源冲突数; 
 ULONG     FastReadNotPossible;    //快速读失败数; 
 ULONG     FastMdlReadNoWait;     //异步MDL快速读数目; 
 ULONG     FastMdlReadWait;      //同步MDL快速读数目; 
 ULONG     FastMdlReadResourceMiss;  //MDL读资源冲突数; 
 ULONG     FastMdlReadNotPossible;   //MDL读失败数; 
 ULONG     MapDataNoWait;       //异步映射数据次数; 
 ULONG     MapDataWait;        //同步映射数据次数; 
 ULONG     MapDataNoWaitMiss;     //异步映射数据冲突次数; 
 ULONG     MapDataWaitMiss;      //同步映射数据冲突次数; 
 ULONG     PinMappedDataCount;     //牵制映射数据数目; 
 ULONG     PinReadNoWait;       //牵制异步读数目; 
 ULONG     PinReadWait;        //牵制同步读数目; 
 ULONG     PinReadNoWaitMiss;     //牵制异步读冲突数目; 
 ULONG     PinReadWaitMiss;      //牵制同步读冲突数目; 
 ULONG     CopyReadNoWait;       //异步拷贝读次数;
 ULONG     CopyReadWait;       //同步拷贝读次数;
 ULONG     CopyReadNoWaitMiss;     //异步拷贝读故障次数;
 ULONG     CopyReadWaitMiss;     //同步拷贝读故障次数; 
 ULONG     MdlReadNoWait;       //异步MDL读次数; 
 ULONG     MdlReadWait;        //同步MDL读次数; 
 ULONG     MdlReadNoWaitMiss;     //异步MDL读故障次数; 
 ULONG     MdlReadWaitMiss;      //同步MDL读故障次数; 
 ULONG     ReadAheadIos;       //向前读操作数目; 
 ULONG     LazyWriteIos;       //LAZY写操作数目; 
 ULONG     LazyWritePages;       //LAZY写页文件数目; 
 ULONG     DataFlushes;        //缓存刷新次数; 
 ULONG     DataPages;         //缓存刷新页数; 
 ULONG     ContextSwitches;      //环境切换数目; 
 ULONG     FirstLevelTbFills;     //第一层缓冲区填充次数; 
 ULONG     SecondLevelTbFills;     //第二层缓冲区填充次数; 
 ULONG     SystemCall;         //系统调用次数;
}SYSTEM_PERFORMANCE_INFORMATION,*PSYSTEM_PERFORMANCE_INFORMATION;

 

typedef struct _SYSTEM_TIMEOFDAY_INFORMATION
{
 LARGE_INTEGER BootTime;    
 LARGE_INTEGER CurrentTime;
 LARGE_INTEGER TimeZoneBias;
 ULONG TimeZoneId;
 ULONG Reserved;
} SYSTEM_TIMEOFDAY_INFORMATION, *PSYSTEM_TIMEOFDAY_INFORMATION;

//include sys header
typedef struct _THREAD_INFO
{
 LARGE_INTEGER CreateTime;
 DWORD dwUnknown1;
 DWORD dwStartAddress;
 DWORD StartEIP;
 DWORD dwOwnerPID;
 DWORD dwThreadId;
 DWORD dwCurrentPriority;
 DWORD dwBasePriority;
 DWORD dwContextSwitches;
 DWORD Unknown;
 DWORD WaitReason;
 
}THREADINFO, *PTHREADINFO;

typedef struct _UNICODE_STRING
{
 USHORT Length;
 USHORT MaxLength;
 PWSTR Buffer;
} UNICODE_STRING;

typedef struct _SYSTEM_PROCESS_INFORMATION
{
 DWORD             dwNextEntryOffset;
 DWORD             dwNumberOfThreads;
 LARGE_INTEGER     qSpareLi1;
 LARGE_INTEGER     qSpareLi2;
 LARGE_INTEGER     qSpareLi3;
 LARGE_INTEGER     qCreateTime;
 LARGE_INTEGER     qUserTime;
 LARGE_INTEGER     qKernelTime;
 UNICODE_STRING     ImageName;
 int                 nBasePriority;
 DWORD             dwProcessId;
 DWORD             dwInheritedFromUniqueProcessId;
 DWORD             dwHandleCount;
 DWORD             dwSessionId;
 ULONG             dwSpareUl3;
 SIZE_T             tPeakVirtualSize;
 SIZE_T             tVirtualSize;
 DWORD             dwPageFaultCount;
 DWORD             dwPeakWorkingSetSize;
 DWORD             dwWorkingSetSize;
 SIZE_T             tQuotaPeakPagedPoolUsage;
 SIZE_T             tQuotaPagedPoolUsage;
 SIZE_T             tQuotaPeakNonPagedPoolUsage;
 SIZE_T             tQuotaNonPagedPoolUsage;
 SIZE_T             tPagefileUsage;
 SIZE_T             tPeakPagefileUsage;
 SIZE_T             tPrivatePageCount;
 LARGE_INTEGER     qReadOperationCount;
 LARGE_INTEGER     qWriteOperationCount;
 LARGE_INTEGER     qOtherOperationCount;
 LARGE_INTEGER     qReadTransferCount;
 LARGE_INTEGER     qWriteTransferCount;
 LARGE_INTEGER     qOtherTransferCount;
}SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;


typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION {
 LARGE_INTEGER IdleTime;
 LARGE_INTEGER KernelTime;
 LARGE_INTEGER UserTime;
 LARGE_INTEGER DpcTime;
 LARGE_INTEGER InterruptTime;
 ULONG InterruptCount;
} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION, *PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION;


typedef struct _SYSTEM_BASIC_INFORMATION
{
 DWORD dwUnknown1; // 0
 ULONG uKeMaximumIncrement; // x86: 0x0002625A or 0x00018730
 ULONG uPageSize; // bytes
 ULONG uMmNumberOfPhysicalPages;
 ULONG uMmLowestPhysicalPage;
 ULONG uMmHighestPhysicalPage;
 ULONG uAllocationGranularity; // bytes
 PVOID pLowestUserAddress;
 PVOID pMmHighestUserAddress;
 LONG * uKeActiveProcessors;
 BYTE bKeNumberProcessors;       //系统cpu个数
 BYTE bUnknown2;
 WORD wUnknown3;
} SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION;

 


=============================================================================

//下面是cpu.cpp文件============================================================

 

 

#include <iostream>

using namespace std;
#include "cpu.h"
#define SystemBasicInformation                   0
#define SystemPerformanceInformation             2
#define SystemTimeOfDayInformation               3
#define SystemProcessInformation                 5  //5  per process SystemProcessesAndThreadsInformation
#define SystemProcessorPerformanceInformation    8  //8  per cpu SystemProcessorCounters

CRITICAL_SECTION    PerfDataCriticalSection;
CpuData            *pPerfDataOld = NULL;          /* Older perf data (saved to establish delta values) */
CpuData            *pPerfData = NULL;             /* Most recent copy of perf data */
ULONG              ProcessCountOld = 0;
ULONG              ProcessCount = 0;
SYSTEM_BASIC_INFORMATION        SystemBasicInfo;
SYSTEM_PERFORMANCE_INFORMATION    SystemPerfInfo;
PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION SystemProcessorTimeInfo = NULL;
LARGE_INTEGER                    liOldIdleTime = {{0,0}};
double                            dbIdleTime;
double                            dbKernelTime;
double                            dbSystemTime;
double                            OldKernelTime = 0;
LARGE_INTEGER                    liOldSystemTime = {{0,0}};

//long (WINAPI *NtQuerySystemInformation )( DWORD, PVOID, DWORD, DWORD* );
typedef LONG (WINAPI *Fun_NtQuerySystemInformation) ( int SystemInformationClass,
              OUT PVOID SystemInformation,
              IN ULONG SystemInformationLength,
              OUT ULONG * pReturnLength OPTIONAL);
Fun_NtQuerySystemInformation NtQuerySystemInformation;

BOOL PerfDataInitialize(void)
{
    SID_IDENTIFIER_AUTHORITY NtSidAuthority = {SECURITY_NT_AUTHORITY};
    NTSTATUS    status;  //typedef LONG NTSTATUS;
 
 InitializeCriticalSection(&PerfDataCriticalSection);
 
 
    NtQuerySystemInformation = (Fun_NtQuerySystemInformation)GetProcAddress(LoadLibraryA("ntdll.dll"), "NtQuerySystemInformation");
 //这里也可以通过GetModuleHandle()获取实例句柄
 /*
 * Get number of processors in the system
    */
    status = NtQuerySystemInformation(SystemBasicInformation, &SystemBasicInfo, sizeof(SystemBasicInfo), NULL);
 
 
    if (status != NO_ERROR)
        return FALSE;
 
  /*
  * Create the SYSTEM Sid
    */
    return TRUE;
}

void PerfDataUninitialize(void)
{
    DeleteCriticalSection(&PerfDataCriticalSection);
}


void GetAllProcCPUUsage()
{
    ULONG                             ulSize;
    LONG                              status;
    LPBYTE                            pBuffer;
    ULONG                             BufferSize;
    PSYSTEM_PROCESS_INFORMATION       pSPI;
    pCpuData                          pPDOld;
    ULONG                             Idx, Idx2;
    HANDLE                            hProcess;
    HANDLE                            hProcessToken;
    double                            CurrentKernelTime;
    SYSTEM_PERFORMANCE_INFORMATION    SysPerfInfo;
    SYSTEM_TIMEOFDAY_INFORMATION      SysTimeInfo;
    PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION SysProcessorTimeInfo;
    ULONG                            Buffer[64]; /* must be 4 bytes aligned! */
 
 
 
    /* Get new system time */
    status = NtQuerySystemInformation (SystemTimeOfDayInformation, &SysTimeInfo, sizeof(SysTimeInfo), 0);
    if (status != NO_ERROR) //如果返回值status不为0,则表示成功
        return;
 
    /* Get new CPU's idle time */
    status = NtQuerySystemInformation (SystemPerformanceInformation, &SysPerfInfo, sizeof(SysPerfInfo), NULL);
    if (status != NO_ERROR)
        return;
 
    /* Get processor time information */
 HANDLE myHeadHandle = GetProcessHeap();
 if(NULL != myHeadHandle)
 {
  SysProcessorTimeInfo =
   (PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION)
   HeapAlloc(myHeadHandle, 0, sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * SystemBasicInfo.bKeNumberProcessors);
  
 }
    status = NtQuerySystemInformation(
  SystemProcessorPerformanceInformation,
  SysProcessorTimeInfo,
  sizeof(SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION) * SystemBasicInfo.bKeNumberProcessors,
  &ulSize);
 
    if (status != NO_ERROR)
        return;
 
  /* Get process information
  * We don't know how much data there is so just keep
  * increasing the buffer size until the call succeeds
    */
    BufferSize = 0;
    do
    {
        BufferSize += 0x10000;
        pBuffer = (LPBYTE)HeapAlloc(myHeadHandle, 0, BufferSize);
  
        status = NtQuerySystemInformation(SystemProcessInformation, pBuffer, BufferSize, &ulSize);
  
        if (status == STATUS_INFO_LENGTH_MISMATCH)
  {
            HeapFree(myHeadHandle, 0, pBuffer);
        }
  
    } while (status == STATUS_INFO_LENGTH_MISMATCH);
 
    EnterCriticalSection(&PerfDataCriticalSection);
 
    /*
    * Save system performance info
    */
    memcpy(&SystemPerfInfo, &SysPerfInfo, sizeof(SYSTEM_PERFORMANCE_INFORMATION));
 
    /*
    * Save system processor time info
    */
    if (SystemProcessorTimeInfo)
 {
        HeapFree(myHeadHandle, 0, SystemProcessorTimeInfo);
    }
    SystemProcessorTimeInfo = SysProcessorTimeInfo;
 
    /*
    * Save system handle info
    */
 
    for (CurrentKernelTime = 0, Idx = 0; Idx < (ULONG)SystemBasicInfo.bKeNumberProcessors; Idx++)
 {
        CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].KernelTime);
        CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].DpcTime);
        CurrentKernelTime += Li2Double(SystemProcessorTimeInfo[Idx].InterruptTime);
    }
 
    /* If it's a first call - skip idle time calcs */
    if (liOldIdleTime.QuadPart != 0)
 {
        /*  CurrentValue = NewValue - OldValue */
        dbIdleTime = Li2Double(SysPerfInfo.IdleTime) - Li2Double(liOldIdleTime);
        dbKernelTime = CurrentKernelTime - OldKernelTime;
        dbSystemTime = Li2Double(SysTimeInfo.CurrentTime) - Li2Double(liOldSystemTime);
  
        /*  CurrentCpuIdle = IdleTime / SystemTime */
        dbIdleTime = dbIdleTime / dbSystemTime;
        dbKernelTime = dbKernelTime / dbSystemTime;
  
        /*  CurrentCpuUsage% = 100 - (CurrentCpuIdle * 100) / NumberOfProcessors */
        dbIdleTime = 100.0 - dbIdleTime * 100.0 / (double)SystemBasicInfo.bKeNumberProcessors; /* + 0.5; */
        dbKernelTime = 100.0 - dbKernelTime * 100.0 / (double)SystemBasicInfo.bKeNumberProcessors; /* + 0.5; */
    }
 
    /* Store new CPU's idle and system time */
    liOldIdleTime = SysPerfInfo.IdleTime;
    liOldSystemTime = SysTimeInfo.CurrentTime;
    OldKernelTime = CurrentKernelTime;
 
    /* Determine the process count
    * We loop through the data we got from NtQuerySystemInformation
    * and count how many structures there are (until RelativeOffset is 0)
    */
 
 ProcessCountOld = ProcessCount;
    ProcessCount = 0;
    pSPI = (PSYSTEM_PROCESS_INFORMATION)pBuffer;
    while (pSPI)
 {
        ProcessCount++;
        if (pSPI->dwNextEntryOffset == 0)
            break;
        pSPI = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pSPI + pSPI->dwNextEntryOffset);
    }
 
    /* Now alloc a new PERFDATA array and fill in the data */
    if (pPerfDataOld)
 {
        HeapFree(GetProcessHeap(), 0, pPerfDataOld);
    }
    pPerfDataOld = pPerfData;
    pPerfData = (pCpuData)HeapAlloc(GetProcessHeap(), 0, sizeof(CpuData) * ProcessCount);
    pSPI = (PSYSTEM_PROCESS_INFORMATION)pBuffer;
    for (Idx = 0; Idx < ProcessCount; Idx++)
 {
        /* Get the old perf data for this process (if any) */
        /* so that we can establish delta values */
        pPDOld = NULL;
        for (Idx2=0; Idx2 < ProcessCountOld; Idx2++)
  {
            if (pPerfDataOld[Idx2].dwPID == pSPI->dwProcessId)
   {
                pPDOld = &pPerfDataOld[Idx2];
                break;
            }
        }
  
        /* Clear out process perf data structure */
        memset(&pPerfData[Idx], 0, sizeof(CpuData));
  
        pPerfData[Idx].dwPID = pSPI->dwProcessId;
  
        if (pPDOld) 
  {
            double    CurTime = Li2Double(pSPI->qKernelTime) + Li2Double(pSPI->qUserTime);
            double    OldTime = Li2Double(pPDOld->qKernelTime) + Li2Double(pPDOld->qUserTime);
            double    CpuTime = (CurTime - OldTime) / dbSystemTime;
            CpuTime = CpuTime * 100.0 / (double)SystemBasicInfo.bKeNumberProcessors; /* + 0.5; */
            pPerfData[Idx].cpuusage = (ULONG)CpuTime;
        }
        pPerfData[Idx].qCputime.QuadPart = pSPI->qUserTime.QuadPart + pSPI->qKernelTime.QuadPart;
  
        if (pSPI->dwProcessId != NULL)
  {
            hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | READ_CONTROL, FALSE, PtrToUlong(pSPI->dwProcessId));
            if (hProcess)
   {
   /* don't query the information of the system process. It's possible but
    returns Administrators as the owner of the process instead of SYSTEM */
                if (pSPI->dwProcessId != 0x4)
                {
                    if (OpenProcessToken(hProcess, TOKEN_QUERY, &hProcessToken))
                    {
                        DWORD RetLen = 0;
                        BOOL Ret;
      
                        Ret = GetTokenInformation(hProcessToken, TokenUser, (LPVOID)Buffer, sizeof(Buffer), &RetLen);
                        CloseHandle(hProcessToken);
     }
     
                }
    
                CloseHandle(hProcess);
            }
        }
        pPerfData[Idx].qUserTime.QuadPart = pSPI->qUserTime.QuadPart;
        pPerfData[Idx].qKernelTime.QuadPart = pSPI->qKernelTime.QuadPart;
        pSPI = (PSYSTEM_PROCESS_INFORMATION)((LPBYTE)pSPI + pSPI->dwNextEntryOffset);
    }
    HeapFree(GetProcessHeap(), 0, pBuffer);
    LeaveCriticalSection(&PerfDataCriticalSection);
}

int PerfGetIndexByProcessId(DWORD dwProcessId)
{
    int Index, FoundIndex = -1;
 
    EnterCriticalSection(&PerfDataCriticalSection);
 
    for (Index = 0; Index < (int)ProcessCount; Index++)
    {
        if ((DWORD)pPerfData[Index].dwPID == dwProcessId)
        {
            FoundIndex = Index;
            break;
        }
    }
 
    LeaveCriticalSection(&PerfDataCriticalSection);
 
    return FoundIndex;
}

 

ULONG PerfDataGetCPUUsage(DWORD dwProcessId)
{
    ULONG    CpuUsage;
    int Index, FoundIndex = -1;
 
    EnterCriticalSection(&PerfDataCriticalSection);
 
 
 for (Index = 0; Index < (int)ProcessCount; Index++)
    {
        if ((DWORD)pPerfData[Index].dwPID == dwProcessId)
        {
            FoundIndex = Index;
            break;
        }
    }
 
    if (Index < (int)ProcessCount)
        CpuUsage = pPerfData[Index].cpuusage;
    else
        CpuUsage = 0;
 
    LeaveCriticalSection(&PerfDataCriticalSection);
 
    return CpuUsage;
}


int main(void)
{
 
 PerfDataInitialize();
 while(1)
 {
  GetAllProcCPUUsage();
  printf("PID:0     CPU:%u/n", PerfDataGetCPUUsage(0));
  printf("PID:2608  CPU:%u/n", PerfDataGetCPUUsage(2608));
  Sleep(1000);
 }
 
  
 return 1;
}