返回

使用Qt在Windows上读取系统内存、CPU和GPU使用情况

后端

在现代的计算环境中,深入了解系统的性能至关重要。监视内存、CPU和GPU的使用情况对于优化性能和诊断潜在问题至关重要。本文将引导您使用Qt和Windows API从Windows系统获取这些关键指标。

系统性能监控的重要性

监控系统性能提供以下好处:

  • 识别性能瓶颈: 识别哪些系统资源限制了应用程序的性能。
  • 故障排除: 帮助识别和诊断与内存、CPU或GPU相关的系统故障。
  • 容量规划: 估计未来的资源需求并规划系统升级。
  • 性能优化: 调整系统配置和代码以提高性能。

使用Qt和Windows API

要从Windows系统读取性能指标,可以使用Qt和Windows API。Qt是一个跨平台应用程序框架,提供与本机平台API的集成。Windows API提供了用于获取系统信息的函数。

读取内存使用情况

使用GlobalMemoryStatusEx函数可以获取系统内存使用情况的信息。此函数返回一个MEMORYSTATUSEX结构,其中包含有关可用内存、已用内存和总内存的信息。

#include <QDebug>

void getMemoryUsage() {
  MEMORYSTATUSEX memoryStatus;
  memoryStatus.dwLength = sizeof(MEMORYSTATUSEX);
  GlobalMemoryStatusEx(&memoryStatus);

  qDebug() << "Total physical memory: " << memoryStatus.ullTotalPhys / 1024 / 1024 << " MB";
  qDebug() << "Available physical memory: " << memoryStatus.ullAvailPhys / 1024 / 1024 << " MB";
  qDebug() << "Used physical memory: " << (memoryStatus.ullTotalPhys - memoryStatus.ullAvailPhys) / 1024 / 1024 << " MB";
}

读取CPU使用情况

使用GetSystemTimes函数可以获取系统CPU使用情况的信息。此函数返回一个FILETIME结构,其中包含有关空闲时间、用户时间和内核时间的累积信息。

#include <QElapsedTimer>
#include <QDebug>

void getCpuUsage() {
  FILETIME idleTime, kernelTime, userTime;
  GetSystemTimes(&idleTime, &kernelTime, &userTime);

  // Convert FILETIME to milliseconds
  QElapsedTimer timer;
  timer.start();
  timer.restart();

  FILETIME newIdleTime, newKernelTime, newUserTime;
  GetSystemTimes(&newIdleTime, &newKernelTime, &newUserTime);

  // Calculate CPU usage
  double idleTimeDiff = (newIdleTime.dwHighDateTime - idleTime.dwHighDateTime) * 4294967296 +
                       (newIdleTime.dwLowDateTime - idleTime.dwLowDateTime);
  double kernelTimeDiff = (newKernelTime.dwHighDateTime - kernelTime.dwHighDateTime) * 4294967296 +
                         (newKernelTime.dwLowDateTime - kernelTime.dwLowDateTime);
  double userTimeDiff = (newUserTime.dwHighDateTime - userTime.dwHighDateTime) * 4294967296 +
                       (newUserTime.dwLowDateTime - userTime.dwLowDateTime);

  double cpuUsage = (kernelTimeDiff + userTimeDiff - idleTimeDiff) / (kernelTimeDiff + userTimeDiff + idleTimeDiff) * 100;

  qDebug() << "CPU usage: " << cpuUsage << "%";
}

读取GPU使用情况

读取GPU使用情况比内存和CPU使用情况复杂。可以使用Windows Management Instrumentation (WMI) 查询来获取GPU信息。

#include <QDebug>
#include <qt_windows.h>
#include <wbemidl.h>

void getGpuUsage() {
  IWbemLocator *locator = nullptr;
  IWbemServices *services = nullptr;
  IEnumWbemClassObject *results = nullptr;

  // Initialize COM
  CoInitialize(NULL);

  // Create the WMI locator
  HRESULT hr = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *)&locator);
  if (FAILED(hr)) {
    qDebug() << "Failed to create WMI locator";
    return;
  }

  // Connect to the WMI namespace
  hr = locator->ConnectServer(L"root\\CIMv2", NULL, NULL, 0, NULL, 0, 0, &services);
  if (FAILED(hr)) {
    qDebug() << "Failed to connect to WMI namespace";
    return;
  }

  // Create the WQL query
  BSTR query = SysAllocString(L"SELECT * FROM Win32_PerfFormattedData_GPUVideoAdapter");
  if (query == NULL) {
    qDebug() << "Failed to create WQL query";
    return;
  }

  // Execute the query
  hr = services->ExecQuery(query, WQL_FLAG_RETURN_IMMEDIATELY, NULL, &results);
  if (FAILED(hr)) {
    qDebug() << "Failed to execute WQL query";
    return;
  }

  // Get the first result
  IWbemClassObject *result;
  ULONG returned;
  hr = results->Next(WBEM_INFINITE, 1, &result, &returned);
  if (FAILED(hr) || returned == 0) {
    qDebug() << "No GPU information found";
    return;
  }

  // Get the GPU usage
  VARIANT gpuUsage;
  hr = result->Get(L"AdapterRAMUsage", 0, &gpuUsage, NULL, NULL);
  if (FAILED(hr)) {
    qDebug() << "Failed to get GPU usage";
    return;
  }

  qDebug() << "GPU usage: " << gpuUsage.uintVal << "%";

  // Cleanup
  result->Release();
  results->Release();
  services->Release();
  locator->Release();
  CoUninitialize();
}