gpt4 book ai didi

delphi - 获取CPU总使用率百分比

转载 作者:行者123 更新时间:2023-12-03 15:05:35 31 4
gpt4 key购买 nike

我正在尝试将 CPU 总使用率的百分比获取到 label1.Caption

我搜索并找到了这些:

enter image description here

我相信有一种简单的方法,比如我们获取 RAM 使用情况。

 GlobalMemoryStatus(RamStats);
Label1.Caption := Format('RAM: %d %%', [RamStats.dwMemoryLoad]);

最佳答案

我找到了一篇文章,determine-cpu-usage-of-current-process-c-and-c ,关于如何获取当前进程的CPU使用率。

现在我们需要做更多的工作,通过将每个正在运行的进程的 CPU 使用百分比相加来计算总 CPU 使用百分比:

function GetTotalCpuUsagePct(): Double;
var
ProcessID: TProcessID;
RunningProcessIDs : TArray<TProcessID>;
begin
Result := 0.0;
RunningProcessIDs := GetRunningProcessIDs;

DeleteNonExistingProcessIDsFromCache(RunningProcessIDs);

for ProcessID in RunningProcessIDs do
Result := Result + GetProcessCpuUsagePct( ProcessID );

end;

获取正在运行的进程 ID 后,我们开始调用DeleteNonExistingProcessIDsFromCache 清理缓存,该缓存保存 GetProcessCpuUsagePct 中所需的先前 Cpu 使用时间:自上次查询以来已停止的每个进程都会从此缓存中删除。

GetProcessCpuUsagePct是核心,它是determine-cpu-usage-of-current-process-c-and-c的翻译。 。此函数需要使用 ProcessID 从 Cpu 使用缓存 LatestProcessCpuUsageCache (单元中的全局)检索先前的读数。请注意,不建议每隔 200 毫秒调用一次 GetToalCpuUsageCpu,因为它可能会给出错误的结果。

function GetProcessCpuUsagePct(ProcessID: TProcessID): Double;
function SubtractFileTime(FileTime1: TFileTIme; FileTime2: TFileTIme): TFileTIme;
begin
Result := TFileTIme(Int64(FileTime1) - Int64(FileTime2));
end;

var
ProcessCpuUsage: TProcessCpuUsage;
ProcessHandle: THandle;
SystemTimes: TSystemTimesRec;
SystemDiffTimes: TSystemTimesRec;
ProcessDiffTimes: TProcessTimesRec;
ProcessTimes: TProcessTimesRec;

SystemTimesIdleTime: TFileTime;
ProcessTimesCreationTime: TFileTime;
ProcessTimesExitTime: TFileTime;
begin
Result := 0.0;

LatestProcessCpuUsageCache.TryGetValue(ProcessID, ProcessCpuUsage);
if ProcessCpuUsage = nil then
begin
ProcessCpuUsage := TProcessCpuUsage.Create;
LatestProcessCpuUsageCache.Add(ProcessID, ProcessCpuUsage);
end;
// method from:
// http://www.philosophicalgeek.com/2009/01/03/determine-cpu-usage-of-current-process-c-and-c/
ProcessHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, ProcessID);
if ProcessHandle <> 0 then
begin
try
if GetSystemTimes(SystemTimesIdleTime, SystemTimes.KernelTime, SystemTimes.UserTime) then
begin
SystemDiffTimes.KernelTime := SubtractFileTime(SystemTimes.KernelTime, ProcessCpuUsage.LastSystemTimes.KernelTime);
SystemDiffTimes.UserTime := SubtractFileTime(SystemTimes.UserTime, ProcessCpuUsage.LastSystemTimes.UserTime);
ProcessCpuUsage.LastSystemTimes := SystemTimes;
if GetProcessTimes(ProcessHandle, ProcessTimesCreationTime, ProcessTimesExitTime, ProcessTimes.KernelTime, ProcessTimes.UserTime) then
begin
ProcessDiffTimes.KernelTime := SubtractFileTime(ProcessTimes.KernelTime, ProcessCpuUsage.LastProcessTimes.KernelTime);
ProcessDiffTimes.UserTime := SubtractFileTime(ProcessTimes.UserTime, ProcessCpuUsage.LastProcessTimes.UserTime);
ProcessCpuUsage.LastProcessTimes := ProcessTimes;
if (Int64(SystemDiffTimes.KernelTime) + Int64(SystemDiffTimes.UserTime)) > 0 then
Result := (Int64(ProcessDiffTimes.KernelTime) + Int64(ProcessDiffTimes.UserTime)) / (Int64(SystemDiffTimes.KernelTime) + Int64(SystemDiffTimes.UserTime)) * 100;
end;
end;
finally
CloseHandle(ProcessHandle);
end;
end;
end;

这是 Windows 7 上结果的屏幕截图。

TotalCpuUsageWin7.png

单位完整列表:

unit uTotalCpuUsagePct;

interface

function GetTotalCpuUsagePct : Double;

implementation

uses
SysUtils, DateUtils, Windows, PsAPI, TlHelp32, ShellAPI, Generics.Collections;

type
TProcessID = DWORD;

TSystemTimesRec = record
KernelTime: TFileTIme;
UserTime: TFileTIme;
end;

TProcessTimesRec = record
KernelTime: TFileTIme;
UserTime: TFileTIme;
end;

TProcessCpuUsage = class
LastSystemTimes: TSystemTimesRec;
LastProcessTimes: TProcessTimesRec;
ProcessCPUusagePercentage: Double;
end;

TProcessCpuUsageList = TObjectDictionary<TProcessID, TProcessCpuUsage>;

var
LatestProcessCpuUsageCache : TProcessCpuUsageList;
LastQueryTime : TDateTime;

(* -------------------------------------------------------------------------- *)

function GetRunningProcessIDs: TArray<TProcessID>;
var
SnapProcHandle: THandle;
ProcEntry: TProcessEntry32;
NextProc: Boolean;
begin
SnapProcHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if SnapProcHandle <> INVALID_HANDLE_VALUE then
begin
try
ProcEntry.dwSize := SizeOf(ProcEntry);
NextProc := Process32First(SnapProcHandle, ProcEntry);
while NextProc do
begin
SetLength(Result, Length(Result) + 1);
Result[Length(Result) - 1] := ProcEntry.th32ProcessID;
NextProc := Process32Next(SnapProcHandle, ProcEntry);
end;
finally
CloseHandle(SnapProcHandle);
end;
TArray.Sort<TProcessID>(Result);
end;
end;

(* -------------------------------------------------------------------------- *)

function GetProcessCpuUsagePct(ProcessID: TProcessID): Double;
function SubtractFileTime(FileTime1: TFileTIme; FileTime2: TFileTIme): TFileTIme;
begin
Result := TFileTIme(Int64(FileTime1) - Int64(FileTime2));
end;

var
ProcessCpuUsage: TProcessCpuUsage;
ProcessHandle: THandle;
SystemTimes: TSystemTimesRec;
SystemDiffTimes: TSystemTimesRec;
ProcessDiffTimes: TProcessTimesRec;
ProcessTimes: TProcessTimesRec;

SystemTimesIdleTime: TFileTime;
ProcessTimesCreationTime: TFileTime;
ProcessTimesExitTime: TFileTime;
begin
Result := 0.0;

LatestProcessCpuUsageCache.TryGetValue(ProcessID, ProcessCpuUsage);
if ProcessCpuUsage = nil then
begin
ProcessCpuUsage := TProcessCpuUsage.Create;
LatestProcessCpuUsageCache.Add(ProcessID, ProcessCpuUsage);
end;
// method from:
// http://www.philosophicalgeek.com/2009/01/03/determine-cpu-usage-of-current-process-c-and-c/
ProcessHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, ProcessID);
if ProcessHandle <> 0 then
begin
try
if GetSystemTimes(SystemTimesIdleTime, SystemTimes.KernelTime, SystemTimes.UserTime) then
begin
SystemDiffTimes.KernelTime := SubtractFileTime(SystemTimes.KernelTime, ProcessCpuUsage.LastSystemTimes.KernelTime);
SystemDiffTimes.UserTime := SubtractFileTime(SystemTimes.UserTime, ProcessCpuUsage.LastSystemTimes.UserTime);
ProcessCpuUsage.LastSystemTimes := SystemTimes;
if GetProcessTimes(ProcessHandle, ProcessTimesCreationTime, ProcessTimesExitTime, ProcessTimes.KernelTime, ProcessTimes.UserTime) then
begin
ProcessDiffTimes.KernelTime := SubtractFileTime(ProcessTimes.KernelTime, ProcessCpuUsage.LastProcessTimes.KernelTime);
ProcessDiffTimes.UserTime := SubtractFileTime(ProcessTimes.UserTime, ProcessCpuUsage.LastProcessTimes.UserTime);
ProcessCpuUsage.LastProcessTimes := ProcessTimes;
if (Int64(SystemDiffTimes.KernelTime) + Int64(SystemDiffTimes.UserTime)) > 0 then
Result := (Int64(ProcessDiffTimes.KernelTime) + Int64(ProcessDiffTimes.UserTime)) / (Int64(SystemDiffTimes.KernelTime) + Int64(SystemDiffTimes.UserTime)) * 100;
end;
end;
finally
CloseHandle(ProcessHandle);
end;
end;
end;

(* -------------------------------------------------------------------------- *)

procedure DeleteNonExistingProcessIDsFromCache(const RunningProcessIDs : TArray<TProcessID>);
var
FoundKeyIdx: Integer;
Keys: TArray<TProcessID>;
n: Integer;
begin
Keys := LatestProcessCpuUsageCache.Keys.ToArray;
for n := Low(Keys) to High(Keys) do
begin
if not TArray.BinarySearch<TProcessID>(RunningProcessIDs, Keys[n], FoundKeyIdx) then
LatestProcessCpuUsageCache.Remove(Keys[n]);
end;
end;

(* -------------------------------------------------------------------------- *)

function GetTotalCpuUsagePct(): Double;
var
ProcessID: TProcessID;
RunningProcessIDs : TArray<TProcessID>;
begin
Result := 0.0;
RunningProcessIDs := GetRunningProcessIDs;

DeleteNonExistingProcessIDsFromCache(RunningProcessIDs);

for ProcessID in RunningProcessIDs do
Result := Result + GetProcessCpuUsagePct( ProcessID );

end;

(* -------------------------------------------------------------------------- *)

initialization
LatestProcessCpuUsageCache := TProcessCpuUsageList.Create( [ doOwnsValues ] );
// init:
GetTotalCpuUsagePct;
finalization
LatestProcessCpuUsageCache.Free;
end.

测试代码:

单元单元1;

interface

uses
Vcl.Forms, System.SysUtils, Vcl.Controls, Vcl.StdCtrls, System.Classes,
Vcl.ExtCtrls,

uTotalCpuUsagePct;

type
TForm1 = class(TForm)
Timer1: TTimer;
Label1: TLabel;
procedure Timer1Timer(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
// start cpu load thread
TThread.CreateAnonymousThread(
procedure
begin
while True do
begin
end;
end).Start;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
TotalCPUusagePercentage: Double;
begin
TotalCPUusagePercentage := GetTotalCpuUsagePct();
Label1.Caption := 'Total cpu: ' + IntToStr(Round(TotalCPUusagePercentage)) + '%';
end;

end.

关于delphi - 获取CPU总使用率百分比,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33571061/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com