【转载】如何计算当前进程的CPU占用率

由于测试一个解码器的项目,很长时间都在反复进行domain knowledge的学习,再加上自己是一个测试新手,对于测试代码撰写啥的还很是生嫩,前一阵被要求在性能测试中,最好在测试时能够计算出解码进程的CPU占用率,做为我们参考的一种性能参数。于是乎搜寻并参考了网络中的N多方法,并在项目中进行实际的实验调试,由此略了解了一点点如何计算进程CPU占用率的代码方法,在此将最终采用的方法之一记录如下:

        刚开始自己从win32 API开始寻找解决策略,后来发现并没有提供直接得到CPU占用率的函数。其过程中考虑过使用NtQuerySystemInformation和GetProcAddress等,通过在一个特定时间段内计算特定进程的总时间和所有进程的总时间,它们的比值就是那个特定进程的确CPU占有率。并参考网上一个高人的改写的函数,以进程的ID作为参数,进程CPU占用率作为返回值,实时计算特定进程的CPU占用。但后来发现,在实际的解码测试时,有些值有时候好像有些问题(不敢确定o)

       后来采用另一种方法,利用WIN 32 API提供的GetProcessTimes()函数可以得到进程占用的CPU时间,通过和实际时间的流逝相比,可以得到某进程占用CPU的比率。具体的方法如下:

 

1.创建一个用来获取当前进程CPU占用率的类,放在/GetCPUPercentage.h

class GetCPUPercentage
{
  private:
    CRITICAL_SECTION cs;  // 供多线程同步的临界区变量
    HANDLE hd;    // 空闲进程的句柄
    DWORD t1;     // 时间戳
    int percent;  // 最近一次计算的CPU占用率

    __int64 oldp;
    __int64 FileTimeToInt64(const FILETIME& time);
    int GetTime(__int64& proc);  // 得到进程占用的CPU时间
  public:
    GetCPUPercentage();
    ~GetCPUPercentage();

    int Get();  // 得到CPU占用率
};

2.创建类的实现,放在/GetCPUPercentage.cpp中,当然要记得include GetCPUPercentage.h

GetCPUPercentage::GetCPUPercentage()
{
  InitializeCriticalSection(&cs);  // 初始化线程临界区变量

  percent = 0;   // 初始的占用率

  DWORD pid = GetCurrentProcessId();   // 得到当前进程id
  hd  = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);  // 通过id得到进程的句柄
  if( hd==NULL ){
     return;
  }

  // 得到初始时刻的值
  GetTime(oldp);
  t1 = GetTickCount();
}

GetCPUPercentage::~GetCPUPercentage()
{
  if( hd!=NULL ){
     CloseHandle(hd);
  }
  DeleteCriticalSection(&cs);
}

// 时间格式转换
__int64 GetCPUPercentage::FileTimeToInt64(const FILETIME& time)
{
  ULARGE_INTEGER tt;
  tt.LowPart = time.dwLowDateTime;
  tt.HighPart = time.dwHighDateTime;
  return(tt.QuadPart);
}

// 得到进程占用的CPU时间 
int GetCPUPercentage::GetTime(__int64& proc)
{
  FILETIME create;
  FILETIME exit;
  FILETIME ker;  // 内核占用时间
  FILETIME user; // 用户占用时间
  FILETIME now;
  if( !GetProcessTimes(hd, &create, &exit, &ker, &user) ){
     return(-1);
  }

  proc = (FileTimeToInt64(ker) + FileTimeToInt64(user))/10000;
  return(0);
}

// 进行换算
int GetCPUPercentage::Get()
{
  if( hd==NULL )
     return(0);

  EnterCriticalSection(&cs);
    DWORD t2 = GetTickCount();
    DWORD dt = t2 - t1;
    if( dt>139 ){  // 毫秒数。用一个比较少的时间片作为计算单位,这个值可修改
       __int64 proc;
       GetTime(proc);

       percent = ((proc-oldp)*100)/dt;

       t1 = t2;
       oldp = proc;
    }
  LeaveCriticalSection(&cs);
  return(percent);
}

 3.在解码进程的相应cpp中,定义一个全局变量

GetCPUPercentage cpu;

 4. 通过调用该类的成员函数Get()

cpu.Get(); //获取当前进程的CPU占用率

 

以上仅是一些工作中遇到问题的记录,如有错误之处,望高人指点!

by lydia

原文出处:http://blog.csdn.net/axdc_qa_team/article/details/4030511

--【转帖】

posted on 2012-05-19 14:15  克劳德曼  阅读(794)  评论(0)    收藏  举报