现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

获取进程对应的CPU使用率

2012-08-15 23:35 工业·编程 ⁄ 共 15728字 ⁄ 字号 暂无评论

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

给我留言

留言无头像?