科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网安全频道如何实时获取系统每个进程占用的CPU

如何实时获取系统每个进程占用的CPU

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

本文的目的是为了和大家讨论一个问题,同时给出一个根据进程ID,来返回该进程实时占用的CPU使用率的函数。希望大家在用这个函数的时候别忘记我的问题。

作者:巧巧读书 来源:巧巧读书 2008年9月2日

关键字: 进程 系统进程 进程管理

  • 评论
  • 分享微博
  • 分享邮件

  本文的目的是为了和大家讨论一个问题,同时给出一个根据进程ID,来返回该进程实时占用的CPU使用率的函数。希望大家在用这个函数的时候别忘记我的问题。

  目前计算进程CPU占用率的方法主要有两种,一种是根据时间来计算,另一种根据注册表计算,我使用的是前者。前者方法原理:在一个特定时间段内计算特定进程的总时间和所有进程的总时间,它们的比值就是那个特定进程的确CPU占有率。

  我写了一个函数(改写),以进程的ID作为参数,进程CPU占用率作为返回值,实时计算特定进程的CPU占用,测试正确。整个程序如下:

  结构定义:

  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 _PROCESS_INFO

  {

  DWORD dwOffset;

  DWORD dwThreadsCount;

  DWORD dwUnused1[6];

  LARGE_INTEGER CreateTime;

  LARGE_INTEGER UserTime;

  LARGE_INTEGER KernelTime;

  UNICODE_STRING ProcessName;

  DWORD dwBasePriority;

  DWORD dwProcessID;

  DWORD dwParentProcessId;

  DWORD dwHandleCount;

  DWORD dwUnused3[2];

  DWORD dwVirtualBytesPeak;

  DWORD dwVirtualBytes;

  ULONG dwPageFaults;

  DWORD dwWorkingSetPeak;

  DWORD dwWorkingSet;

  DWORD dwQuotaPeakPagedPoolUsage;

  DWORD dwQuotaPagedPoolUsage;

  DWORD dwQuotaPeakNonPagedPoolUsage;

  DWORD dwQuotaNonPagedPoolUsage;

  DWORD dwPageFileUsage;

  DWORD dwPageFileUsagePeak;

  DWORD dCommitCharge;

  THREADINFO ThreadSysInfo[1];

  } PROCESSINFO, *PPROCESSINFO;

  函数定义:

  int Button2Click(int id);//参数是进程ID

  函数实体:

  int Button2Click(int id)

  {

  int cpuusage;

  PVOID pProcInfo = NULL;

  DWORD dwInfoSize = 0x20000;

  PPROCESSINFO pProcessInfo;

  DWORD dwWorkingSet;

  long ( __stdcall *NtQuerySystemInformation )( DWORD, PVOID, DWORD, DWORD );

  static __int64 LastTotalProcessCPUUsage = 0;

  static __int64 LastCurrentProcessCPUUsage = 0;

  int CurrentDelta;

  int TotalDelta;

  __int64 TotalProcessCPUUsage = 0;

  __int64 CurrentProcessCPUUsage = 0;

  /////////////////////////////////

  pProcInfo = (PVOID)(new byte[dwInfoSize]);

  NtQuerySystemInformation = (long(__stdcall*)(DWORD,PVOID,DWORD,DWORD))

  GetProcAddress( GetModuleHandle( "ntdll.dll" ),"NtQuerySystemInformation" );

  NtQuerySystemInformation(5,pProcInfo,dwInfoSize,0);

  pProcessInfo = (PPROCESSINFO)pProcInfo;

  do

  {

  TotalProcessCPUUsage += (__int64)pProcessInfo->KernelTime.QuadPart + (__int64)pProcessInfo->UserTime.QuadPart;

  if(pProcessInfo->dwProcessID == id)

  {

  dwWorkingSet = pProcessInfo->dwWorkingSet;

  CurrentProcessCPUUsage += (__int64)pProcessInfo->KernelTime.QuadPart + (__int64)pProcessInfo->UserTime.QuadPart;

  }

  /////////

  if(pProcessInfo->dwOffset == 0)

  {

  break;

  }

  pProcessInfo = (PPROCESSINFO)((byte*)pProcessInfo + pProcessInfo->dwOffset);

  }

  while(true);

  TotalDelta = TotalProcessCPUUsage - LastTotalProcessCPUUsage;

  CurrentDelta = CurrentProcessCPUUsage - LastCurrentProcessCPUUsage;

  if(TotalDelta != 0)

  cpuusage = 100 * CurrentDelta / TotalDelta;

  //this->Caption = "CPU = "+ IntToStr(100 * CurrentDelta / TotalDelta) +

  //"Memory = "+ IntToStr(dwWorkingSet / 1024) "K";

  LastTotalProcessCPUUsage = TotalProcessCPUUsage;

  LastCurrentProcessCPUUsage = CurrentProcessCPUUsage;

  delete[] pProcInfo;

  return cpuusage;

  }

  {

  while(true)

  {

  int s = Button2Click(0);//在此把进程ID作为参数传入

  printf("%d\n",s);

  Sleep(1000);

  }

  return 0;

  }

  ///////////////////////////////

  以上代码运行非常正常

  ///////////////////////////////

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章