获取进程对应的CPU使用率

    技术2026-04-20  5

    //这是头文件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 headertypedef 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;}

    最新回复(0)