编写QT应用,涉及到查看CPU占用率, 将当前程序的pid的句柄改成其他的程序的pid 值即可查看其他指定程序的pid值了。(添加了一个方法根据程序名称获取其PID值)
在如何计算当前进程的CPU占用率_AXDC_QA_Team的专栏-CSDN博客_进程的cpu利用率怎么计算这个作者的查看cpu占用率的方法,基础之上添加了两个方法,更贴合我自己的项目了。测试代码如下!
前一阵被要求在性能测试中,最好在测试时能够计算出解码进程的CPU占用率,做为我们参考的一种性能参数。于是乎搜寻并参考了网络中的N多方法,并在项目中进行实际的实验调试,由此略了解了一点点如何计算进程CPU占用率的代码方法,在此将最终采用的方法之一记录如下:
刚开始自己从win32 API开始寻找解决策略,后来发现并没有提供直接得到CPU占用率的函数。其过程中考虑过使用NtQuerySystemInformation和GetProcAddress等,通过在一个特定时间段内计算特定进程的总时间和所有进程的总时间,它们的比值就是那个特定进程的确CPU占有率。并参考网上一个高人的改写的函数,以进程的ID作为参数,进程CPU占用率作为返回值,实时计算特定进程的CPU占用。但后来发现,在实际的解码测试时,有些值有时候好像有些问题(不敢确定o)
后来采用另一种方法,利用WIN 32 API提供的GetProcessTimes()函数可以得到进程占用的CPU时间,通过和实际时间的流逝相比,可以得到某进程占用CPU的比率。具体的方法如下:
1.创建一个用来获取当前进程CPU占用率的类,放在/mainwindow.h中
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QObject>
#include <QLabel>
#include <QProcess>
#include <QTimer>
#include <QDebug>
#ifdef Q_OS_WIN
#include "windows.h"
#include <tlhelp32.h>
#endif
#define MB (1024 * 1024)
#define KB (1024)
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
DWORD IsRun(QString strName);
private:
Ui::MainWindow *ui;
private:
CRITICAL_SECTION cs; // 供多线程同步的临界区变量
HANDLE hd; // 空闲进程的句柄
DWORD t1; // 时间戳
int percent; // 最近一次计算的CPU占用率
__int64 oldp;
__int64 FileTimeToInt64(const FILETIME& time);
int GetTime(__int64& proc); // 得到进程占用的CPU时间
int Get(); // 得到CPU占用率
};
#endif // MAINWINDOW_H
2.创建类的实现,放在/mainwindow.cpp中,当然要记得include mainwindow.h哦
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
InitializeCriticalSection(&cs);
percent = 0; // 初始的占用率
DWORD pid = IsRun("SipPhone.exe"); // 得到当前进程id
//DWORD pid = IsRun("vmware-view.exe");
// DWORD pid = IsRun("gwclient.exe");
//DWORD pid = IsRun("Chrome.exe");
//DWORD pid = GetCurrentProcessId();
//DWORD pid = 0;
hd = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); // 通过id得到进程的句柄
if( hd==NULL ){
return;
}
// 得到初始时刻的值
GetTime(oldp);
t1 = GetTickCount();
int pro = Get();
qDebug() << "CPU占用"<< pro << "%";
connect(ui->pushButton,&QPushButton::clicked,this,&MainWindow::Get);
qDebug() << "CPU占用"<< pro << "%";
}
DWORD MainWindow::IsRun(QString strName)
{
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(pe32);
HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if(hProcessSnap != INVALID_HANDLE_VALUE)
{
BOOL bMore = Process32First(hProcessSnap,&pe32);
while(bMore)
{
// printf("进程名称:%s\n",pe32.szExeFile);
// printf("进程ID:%u\n\n",pe32.th32ProcessID);
qDebug() << pe32.th32ProcessID;
QString exeName = (QString::fromUtf16(reinterpret_cast<const unsigned short *>(pe32.szExeFile)));
if(exeName == strName)
{
/*可以根据程序名称获取进程ID*/
qDebug() << pe32.th32ProcessID; qDebug() << pe32.th32ProcessID;
CloseHandle(hProcessSnap);
return pe32.th32ProcessID;
}
bMore = Process32Next(hProcessSnap,&pe32);
}
}
CloseHandle(hProcessSnap);
return 0;
}
MainWindow::~MainWindow()
{
if( hd!=NULL ){
CloseHandle(hd);
}
DeleteCriticalSection(&cs);
delete ui;
}
// 时间格式转换
__int64 MainWindow::FileTimeToInt64(const FILETIME& time)
{
ULARGE_INTEGER tt;
tt.LowPart = time.dwLowDateTime;
tt.HighPart = time.dwHighDateTime;
return(tt.QuadPart);
}
// 得到进程占用的CPU时间
int MainWindow::GetTime(__int64& proc)
{
FILETIME create;
FILETIME exit;
FILETIME ker; // 内核占用时间
FILETIME user; // 用户占用时间
if( !GetProcessTimes(hd, &create, &exit, &ker, &user) ){
return(-1);
}
proc = (FileTimeToInt64(ker) + FileTimeToInt64(user))/10000;
return(0);
}
// 进行换算
int MainWindow::Get(){
qDebug() << "CPU占用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);
qDebug() << "CPU占用"<< percent << "%";
return(percent);
}
3.在解码进程的相应cpp中,定义一个全局变量
GetCPUPercentage cpu;
4. 通过调用该类的成员函数Get()
cpu.Get(); //获取当前进程的CPU占用率
因为我这个是通过点击按钮,信号与槽来做的粗略测试是否可以实现,可能会有一定误差,可以改为定时发起查询。
以上仅是一些工作中遇到问题的记录,如有错误之处,望高人指点!