You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Delphi 11获取自身进程的实时CPU使用率(与任务管理器一致)

Delphi 11 获取自身进程CPU使用率(与任务管理器一致)

要实现和Windows任务管理器中“CPU”列完全一致的进程CPU使用率,需要通过两次采样进程CPU时间与系统总CPU时间,计算两者的差值比例,同时考虑多核CPU的总处理能力。以下是具体实现:

核心思路

任务管理器的进程CPU使用率计算公式为:
进程CPU使用率 = (当前进程CPU时间 - 上次进程CPU时间) / (当前系统总CPU时间 - 上次系统总CPU时间) * 100
其中系统总CPU时间是所有CPU核心的用户态+内核态时间总和(排除空闲时间),这样计算出的数值会和任务管理器完全匹配(包括多核场景下超过100%的情况)。

完整代码实现

unit ProcessCPUUsage;

interface

uses
  Winapi.Windows, System.SysUtils;

type
  TProcessCPUUsage = class
  private
    FLastProcessUserTime: Int64;
    FLastProcessKernelTime: Int64;
    FLastSystemIdleTime: Int64;
    FLastSystemKernelTime: Int64;
    FLastSystemUserTime: Int64;
    FProcessHandle: THandle;
    function GetSystemTotalTime: Int64;
  public
    constructor Create;
    destructor Destroy; override;
    function GetCPUUsage: Double;
  end;

implementation

constructor TProcessCPUUsage.Create;
begin
  inherited;
  // 获取当前进程句柄(系统自动管理,无需手动关闭)
  FProcessHandle := GetCurrentProcess;
  // 初始化首次采样数据
  GetProcessTimes(FProcessHandle, nil, nil, PLargeInteger(@FLastProcessKernelTime), PLargeInteger(@FLastProcessUserTime));
  GetSystemTimes(PLargeInteger(@FLastSystemIdleTime), PLargeInteger(@FLastSystemKernelTime), PLargeInteger(@FLastSystemUserTime));
end;

destructor TProcessCPUUsage.Destroy;
begin
  inherited;
end;

function TProcessCPUUsage.GetSystemTotalTime: Int64;
begin
  // 系统总CPU时间 = 用户态时间 + 内核态时间 - 空闲时间(空闲时间属于内核态的无效占用,需排除)
  Result := (FLastSystemUserTime + FLastSystemKernelTime) - FLastSystemIdleTime;
end;

function TProcessCPUUsage.GetCPUUsage: Double;
var
  CurrentProcessUserTime, CurrentProcessKernelTime: Int64;
  CurrentSystemIdleTime, CurrentSystemKernelTime, CurrentSystemUserTime: Int64;
  ProcessTimeDiff, SystemTimeDiff: Int64;
begin
  Result := 0;
  // 获取当前进程CPU时间
  if not GetProcessTimes(FProcessHandle, nil, nil, PLargeInteger(@CurrentProcessKernelTime), PLargeInteger(@CurrentProcessUserTime)) then
    Exit;
  // 获取当前系统CPU时间
  if not GetSystemTimes(PLargeInteger(@CurrentSystemIdleTime), PLargeInteger(@CurrentSystemKernelTime), PLargeInteger(@CurrentSystemUserTime)) then
    Exit;

  // 计算两次采样的时间差
  ProcessTimeDiff := (CurrentProcessUserTime - FLastProcessUserTime) + (CurrentProcessKernelTime - FLastProcessKernelTime);
  SystemTimeDiff := ((CurrentSystemUserTime + CurrentSystemKernelTime) - CurrentSystemIdleTime) - GetSystemTotalTime;

  if SystemTimeDiff > 0 then
    Result := (ProcessTimeDiff / SystemTimeDiff) * 100;

  // 更新采样基准数据
  FLastProcessUserTime := CurrentProcessUserTime;
  FLastProcessKernelTime := CurrentProcessKernelTime;
  FLastSystemIdleTime := CurrentSystemIdleTime;
  FLastSystemKernelTime := CurrentSystemKernelTime;
  FLastSystemUserTime := CurrentSystemUserTime;
end;

end.

使用示例

在窗体中添加一个TTimer(设置Interval为1000,即1秒刷新一次)和一个TLabel显示CPU使用率:

procedure TForm1.FormCreate(Sender: TObject);
begin
  FCPUUsage := TProcessCPUUsage.Create;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var
  Usage: Double;
begin
  Usage := FCPUUsage.GetCPUUsage;
  Label1.Caption := Format('自身进程CPU使用率: %.1f%%', [Usage]);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  FCPUUsage.Free;
end;

注意事项

  • 首次调用GetCPUUsage会返回0,因为没有前一次采样数据作对比,第二次及以后调用才能得到有效数值。
  • 定时器间隔建议设为1秒,和任务管理器默认刷新频率一致,数值会完全同步。
  • 若需获取其他进程的CPU使用率,只需将FProcessHandle替换为目标进程的句柄(通过OpenProcess获取)。

内容的提问来源于stack exchange,提问作者delphirules

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 04:10:31