Files

169 lines
5.6 KiB
C++

#include <string>
#include <Windows.h>
#include <ios>
#include <qthread.h>
#include <fileManager.h>
class hardwareMonitor :public QThread
{
public:
int outputCnt =10;
struct CPUUsage {
DWORD_PTR coreId;
double usage;
};
struct oneTimeData
{
QString time;
std::vector<CPUUsage>cpuState;
std::vector<double>memState;
};
std::vector<CPUUsage> getCPUUsagePerCore() {
std::vector<CPUUsage> coreUsages;
int numCores = sysInfo.dwNumberOfProcessors;
std::vector<FILETIME> idleTimes(numCores), kernelTimes(numCores), userTimes(numCores);
std::vector<FILETIME> prevIdleTimes(numCores), prevKernelTimes(numCores), prevUserTimes(numCores);
// 初始获取
GetSystemTimes(&prevIdleTimes[0], &prevKernelTimes[0], &prevUserTimes[0]);
Sleep(100);
// 获取再次的 CPU 时间
GetSystemTimes(&idleTimes[0], &kernelTimes[0], &userTimes[0]);
for (int i = 0; i < numCores; ++i) {
ULARGE_INTEGER idleTime, kernelTime, userTime;
ULARGE_INTEGER prevIdleTime, prevKernelTime, prevUserTime;
idleTime.LowPart = idleTimes[i].dwLowDateTime;
idleTime.HighPart = idleTimes[i].dwHighDateTime;
kernelTime.LowPart = kernelTimes[i].dwLowDateTime;
kernelTime.HighPart = kernelTimes[i].dwHighDateTime;
userTime.LowPart = userTimes[i].dwLowDateTime;
userTime.HighPart = userTimes[i].dwHighDateTime;
prevIdleTime.LowPart = prevIdleTimes[i].dwLowDateTime;
prevIdleTime.HighPart = prevIdleTimes[i].dwHighDateTime;
prevKernelTime.LowPart = prevKernelTimes[i].dwLowDateTime;
prevKernelTime.HighPart = prevKernelTimes[i].dwHighDateTime;
prevUserTime.LowPart = prevUserTimes[i].dwLowDateTime;
prevUserTime.HighPart = prevUserTimes[i].dwHighDateTime;
ULONGLONG totalIdle = idleTime.QuadPart - prevIdleTime.QuadPart;
ULONGLONG totalKernel = kernelTime.QuadPart - prevKernelTime.QuadPart;
ULONGLONG totalUser = userTime.QuadPart - prevUserTime.QuadPart;
ULONGLONG total = totalKernel + totalUser;
CPUUsage usage;
usage.coreId = i;
usage.usage = (total > 0) ? (static_cast<double>(total - totalIdle) / total) * 100.0 : 0.0;
coreUsages.push_back(usage);
}
return coreUsages;
}
std::vector<double> getMemState()
{
MEMORYSTATUSEX memInfo;
memInfo.dwLength = sizeof(MEMORYSTATUSEX);
if (GlobalMemoryStatusEx(&memInfo)) {
// 获取总物理内存和已用内存
DWORDLONG totalPhysical = memInfo.ullTotalPhys;
DWORDLONG usedPhysical = memInfo.ullTotalPhys - memInfo.ullAvailPhys;
// 获取总虚拟内存和已用虚拟内存
DWORDLONG totalVirtual = memInfo.ullTotalVirtual;
DWORDLONG usedVirtual = memInfo.ullTotalVirtual - memInfo.ullAvailVirtual;
// 计算内存占用率
double physicalMemoryUsage = (static_cast<double>(usedPhysical) / totalPhysical) * 100.0;
double virtualMemoryUsage = (static_cast<double>(usedVirtual) / totalVirtual) * 100.0;
return { physicalMemoryUsage,virtualMemoryUsage };
}
else
return { 0,0 };
}
hardwareMonitor()
{
this->start();
}
~hardwareMonitor()
{
runFlag = false;
}
void writeCsv(std::vector<oneTimeData>&State) {
if (State.size() == 0)
{
std::cerr << "hw数据为空! " << std::endl;
return;
}
fileManager::createDirectoryIfNotExists("./Log");
QString fileName("./Log/" + QDate::currentDate().toString("yyyy-MM-dd") + "hwMonitor.csv");
QFile file(fileName);
bool isEmpty = !file.exists() || file.size() == 0;
// 打开文件进行写入
if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append)) {
std::cerr << "无法打开文件进行写入: " << file.errorString().toStdString() << std::endl;
return;
}
QTextStream out(&file);
// 表头
if(isEmpty == true)
{
QStringList headers;
headers.append("getTime");
for (int i = 0; i < State[0].cpuState.size(); i++)
headers.append("CORE" + QString::number(i));
headers.append("pMem,vMem");
out << headers.join(",") << "\n";
}
// 循环写入数据
for(auto& data: State)
{
QStringList csvData;
csvData.append(data.time);
for (auto& cpuData : data.cpuState)
csvData.append(QString::number(cpuData.usage));
for (auto& memuData : data.memState)
csvData.append(QString::number(memuData));
out << csvData.join(",") << "\n";
}
// 关闭文件
file.close();
State.clear();//成功写入后清除
}
void run()
{
//初始化
GetSystemInfo(&sysInfo);
//循环读取
std::vector< oneTimeData> datas;
while (runFlag)
{
oneTimeData _oneTimeData;
//CPU占用
_oneTimeData.cpuState = getCPUUsagePerCore();
//内存占用
_oneTimeData.memState= getMemState();
//记录时间
_oneTimeData.time = QTime::currentTime().toString("HH:mm:ss");
QThread::msleep(10);
datas.push_back(_oneTimeData);
if (datas.size() > outputCnt)
{
writeCsv(datas);
}
}
}
private:
SYSTEM_INFO sysInfo;
bool runFlag = true;
};
#pragma once