Qt/C++获取实时CPU使用率

首先了解一下CPU使用率的计算方式,无论是单个进程cpu占用率还是系统整个cpu使用率,都是一样的计算公式:

  • cpu使用率 = 运行时间 / 间隔时间 
  • 运行时间 = 内核时间 + 用户时间 - 空闲时间
  • 间隔时间 =  内核时间 + 用户时间

根据上述公式的原理,在计算CPU使用率时需要阻塞/等待线程若干时间,一般这个时间为500ms/1000ms。由于需要阻塞线程,所以计算CPU使用率的函数是绝对不能写在主线程里的,因此另开一个线程用以计算该公式,代码如下:

worker.h(开启从线程计算CPU占用)

#pragma once

#include "windows.h"
#include <QObject>
#include <QThread>


class Worker : public QObject
{
	Q_OBJECT
public:
	explicit Worker(QObject* parent = nullptr) { };

protected:
	//时间转换
	__int64 Filetime2Int64(const FILETIME* ftime)
	{
		LARGE_INTEGER li;
		li.LowPart = ftime->dwLowDateTime;
		li.HighPart = ftime->dwHighDateTime;
		return li.QuadPart;
	}
	//两个时间相减运算
	__int64 CompareFileTime(FILETIME preTime, FILETIME nowTime)
	{
		return this->Filetime2Int64(&nowTime) - this->Filetime2Int64(&preTime);
	}

signals:
	void resultReady(const int dosage); // 向外界发送结果

public slots:
	void calCpuUsage()// 耗时操作
	{
		HANDLE hEvent;
		bool res;
		static FILETIME preIdleTime;
		static FILETIME preKernelTime;
		static FILETIME preUserTime;

		FILETIME idleTime;
		FILETIME kernelTime;
		FILETIME userTime;

		res = GetSystemTimes(&idleTime, &kernelTime, &userTime);

		preIdleTime = idleTime;
		preKernelTime = kernelTime;
		preUserTime = userTime;

		hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

		WaitForSingleObject(hEvent, 500);	//等待500毫秒

		res = GetSystemTimes(&idleTime, &kernelTime, &userTime);

		int idle = CompareFileTime(preIdleTime, idleTime);
		int kernel = CompareFileTime(preKernelTime, kernelTime);
		int user = CompareFileTime(preUserTime, userTime);

		auto nCpuRate = (int)ceil(100.0 * (kernel + user - idle) / (kernel + user));

		emit resultReady(nCpuRate);
	}
};

Controller.h

#pragma once

#include <QObject>
#include <QThread>
#include "worker.h"

class Controller : public QObject
{
	Q_OBJECT
public:
	explicit Controller(QObject* parent = nullptr);
	~Controller();

	int getCpuUsage();

signals:
	void startRunning(); // 用于触发新线程中的耗时操作函数

public slots:
	void on_receivResult(const int dosage); // 接收新线程中的结果

private:
	QThread m_workThread;
	Worker* m_worker;

	int cpuDosage = 0;
};

 Controller.cpp

#include "Controller.h"

#include <QThread>
#include <QDebug>

Controller::Controller(QObject* parent) : QObject(parent)
{
	m_worker = new Worker();
	m_worker->moveToThread(&m_workThread);

	connect(this, &Controller::startRunning, m_worker, &Worker::calCpuUsage);
	connect(&m_workThread, &QThread::finished, m_worker, &QObject::deleteLater);
	connect(m_worker, &Worker::resultReady, this, &Controller::on_receivResult);
}

Controller::~Controller()
{
	m_workThread.quit();
	m_workThread.wait();
}

int Controller::getCpuUsage()
{
	m_workThread.start();
	emit startRunning();
	return cpuDosage;
}

void Controller::on_receivResult(const int dosage)
{
	cpuDosage = dosage;
}

 

使用方法:实例化Controller,调用getCpuUsage()即可。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值