如何获取Windows上每个线程的CPU使用率(win32)

时间:2020-12-22 07:04:53

Looking for Win32 API functions, C++ or Delphi sample code that tells me the CPU usage (percent and/or total CPU time) of a thread (not the total for a process). I have the thread ID.

寻找Win32 API函数,C ++或Delphi示例代码,它告诉我线程的CPU使用率(百分比和/或总CPU时间)(而不是进程的总和)。我有线程ID。

I know that Sysinternals Process Explorer can display this information, but I need this information inside my program.

我知道Sysinternals Process Explorer可以显示这些信息,但我在程序中需要这些信息。

6 个解决方案

#1


22  

You must use these functions to get the cpu usage per thread and process.

您必须使用这些函数来获取每个线程和进程的cpu使用情况。

GetThreadTimes (Retrieves timing information for the specified thread.)

GetThreadTimes(检索指定线程的计时信息。)

GetProcessTimes (Retrieves timing information for the specified process.)

GetProcessTimes(检索指定进程的计时信息。)

GetSystemTime (Retrieves the current system date and time. The system time is expressed in Coordinated Universal Time UTC)

GetSystemTime(检索当前系统日期和时间。系统时间以协调世界时UTC表示)

Here a excellent article from Dr. Dobb's Win32 Performance Measurement Options

这是Dobb博士Win32性能测量选项的优秀文章

Bye.

#2


10  

The data you are refering to is available using specific WMI calls. You can query Win32_Process to get all sorts of process specific information, and query Win32_PerfFormattedData_PerfProc_Process to get the thread count, and given a handle to a thread (what I believe your looking for) you can query Win32_PerfRawData_PerfProc_Thread to get the percent of processor time used.

您使用特定的WMI调用可以获得您要引用的数据。您可以查询Win32_Process以获取各种特定于进程的信息,并查询Win32_PerfFormattedData_PerfProc_Process以获取线程计数,并给出一个线程句柄(我相信您正在寻找),您可以查询Win32_PerfRawData_PerfProc_Thread以获得所用处理器时间的百分比。

There is a library available for Delphi which provides wrappers for most of the WMI queries, however it will take some experimentation to get the exact query your looking for. The query syntax is very sql like, for example on my system to return the percent of processor time for threadid 8, for process id 4 is:

有一个可用于Delphi的库,它为大多数WMI查询提供包装器,但是需要一些实验才能获得您想要的确切查询。查询语法非常像sql,例如在我的系统上返回threadid 8的处理器时间百分比,因为进程id 4是:

SELECT PercentProcessorTime FROM Win32_PerfRawData_PerfProc_Thread 
  WHERE IdProcess=4 and IdThread=8

Most of the programs which present statistical information about running processes now use WMI to query for this information.

现在,大多数提供有关正在运行的进程的统计信息的程序都使用WMI来查询此信息。

#3


7  

Is important to know that in certain situations, the execution time of a thread may be worthless. The execution times of each thread are updated every 15 milliseconds usually for multi-core systems, so if a thread completes its task before this time, the runtime will be reset. More details can be obtained on the link: GetThreadTimes function and I was surprised by the result!
and Why GetThreadTimes is wrong

重要的是要知道在某些情况下,线程的执行时间可能毫无价值。对于多核系统,每个线程的执行时间通常每15毫秒更新一次,因此如果线程在此时间之前完成其任务,则将重置运行时。更多细节可以在链接上获得:GetThreadTimes函数,我对结果感到惊讶!以及为什么GetThreadTimes是错误的

#4


6  

With the help of RRUZ's answer above I finally came up with this code for Borland Delphi:

在RRUZ上面的回答的帮助下,我终于想出了Borland Delphi的代码:

const
  THREAD_TERMINATE                 = $0001;
  THREAD_SUSPEND_RESUME            = $0002;
  THREAD_GET_CONTEXT               = $0008;
  THREAD_SET_CONTEXT               = $0010;
  THREAD_SET_INFORMATION           = $0020;
  THREAD_QUERY_INFORMATION         = $0040;
  THREAD_SET_THREAD_TOKEN          = $0080;
  THREAD_IMPERSONATE               = $0100;
  THREAD_DIRECT_IMPERSONATION      = $0200;
  THREAD_SET_LIMITED_INFORMATION   = $0400;
  THREAD_QUERY_LIMITED_INFORMATION = $0800;
  THREAD_ALL_ACCESS                = STANDARD_RIGHTS_REQUIRED or SYNCHRONIZE or $03FF;

function OpenThread(dwDesiredAccess: DWord;
                    bInheritHandle: Bool;
                    dwThreadId: DWord): DWord; stdcall; external 'kernel32.dll';


procedure TForm1.Button1Click(Sender: TObject);
var iii:integer;
    handle:thandle;
    creationtime,exittime,kerneltime,usertime:filetime;
begin
  Handle:=OpenThread(THREAD_SET_INFORMATION or THREAD_QUERY_INFORMATION, False, windows.GetCurrentThreadId);
  if handle<>0 then
  begin
    getthreadtimes(Handle,creationtime,exittime,kerneltime,usertime);
    label1.caption:='Total time for Thread #'+inttostr(windows.GetCurrentThreadId)+': '+inttostr( (int64(kerneltime)+int64(usertime)) div 1000 )+' msec';
    CloseHandle(Handle);
  end;
end;

#5


4  

Using "GetThreadTimes"? If you measure the time between calls to "GetThreadTimes" and store the previous user and/or kernel times then you know how much time the thread has had since you last checked. You also know how much time has elapsed in the mean time and thus you can work out how much CPU time was used. It would be best (for timer resolution reasons) to make this check every second or so and work out its average CPU usage over that second.

使用“GetThreadTimes”?如果您测量调用“GetThreadTimes”并存储先前用户和/或内核时间之间的时间,那么您就知道自上次检查以来线程已经有多长时间了。您还知道平均时间已经过了多少时间,因此您可以计算出使用了多少CPU时间。最好(出于计时器分辨率的原因)每隔一秒左右进行一次检查,并计算出其平均CPU使用率。

#6


1  

Here is a simple WMI query wrapper. With help of it you can call this to get data:

这是一个简单的WMI查询包装器。借助它,您可以调用它来获取数据:

getWmiQueryResult(L"SELECT PercentProcessorTime FROM Win32_PerfRawData_PerfProc_Thread WHERE IdProcess=4 and IdThread=8", L"PercentProcessorTime ");

Also you might want to look at the Win32_PerfRawData_PerfProc_Thread documentation to see what other properties you can fetch.

您还可以查看Win32_PerfRawData_PerfProc_Thread文档,了解您可以获取的其他属性。

#1


22  

You must use these functions to get the cpu usage per thread and process.

您必须使用这些函数来获取每个线程和进程的cpu使用情况。

GetThreadTimes (Retrieves timing information for the specified thread.)

GetThreadTimes(检索指定线程的计时信息。)

GetProcessTimes (Retrieves timing information for the specified process.)

GetProcessTimes(检索指定进程的计时信息。)

GetSystemTime (Retrieves the current system date and time. The system time is expressed in Coordinated Universal Time UTC)

GetSystemTime(检索当前系统日期和时间。系统时间以协调世界时UTC表示)

Here a excellent article from Dr. Dobb's Win32 Performance Measurement Options

这是Dobb博士Win32性能测量选项的优秀文章

Bye.

#2


10  

The data you are refering to is available using specific WMI calls. You can query Win32_Process to get all sorts of process specific information, and query Win32_PerfFormattedData_PerfProc_Process to get the thread count, and given a handle to a thread (what I believe your looking for) you can query Win32_PerfRawData_PerfProc_Thread to get the percent of processor time used.

您使用特定的WMI调用可以获得您要引用的数据。您可以查询Win32_Process以获取各种特定于进程的信息,并查询Win32_PerfFormattedData_PerfProc_Process以获取线程计数,并给出一个线程句柄(我相信您正在寻找),您可以查询Win32_PerfRawData_PerfProc_Thread以获得所用处理器时间的百分比。

There is a library available for Delphi which provides wrappers for most of the WMI queries, however it will take some experimentation to get the exact query your looking for. The query syntax is very sql like, for example on my system to return the percent of processor time for threadid 8, for process id 4 is:

有一个可用于Delphi的库,它为大多数WMI查询提供包装器,但是需要一些实验才能获得您想要的确切查询。查询语法非常像sql,例如在我的系统上返回threadid 8的处理器时间百分比,因为进程id 4是:

SELECT PercentProcessorTime FROM Win32_PerfRawData_PerfProc_Thread 
  WHERE IdProcess=4 and IdThread=8

Most of the programs which present statistical information about running processes now use WMI to query for this information.

现在,大多数提供有关正在运行的进程的统计信息的程序都使用WMI来查询此信息。

#3


7  

Is important to know that in certain situations, the execution time of a thread may be worthless. The execution times of each thread are updated every 15 milliseconds usually for multi-core systems, so if a thread completes its task before this time, the runtime will be reset. More details can be obtained on the link: GetThreadTimes function and I was surprised by the result!
and Why GetThreadTimes is wrong

重要的是要知道在某些情况下,线程的执行时间可能毫无价值。对于多核系统,每个线程的执行时间通常每15毫秒更新一次,因此如果线程在此时间之前完成其任务,则将重置运行时。更多细节可以在链接上获得:GetThreadTimes函数,我对结果感到惊讶!以及为什么GetThreadTimes是错误的

#4


6  

With the help of RRUZ's answer above I finally came up with this code for Borland Delphi:

在RRUZ上面的回答的帮助下,我终于想出了Borland Delphi的代码:

const
  THREAD_TERMINATE                 = $0001;
  THREAD_SUSPEND_RESUME            = $0002;
  THREAD_GET_CONTEXT               = $0008;
  THREAD_SET_CONTEXT               = $0010;
  THREAD_SET_INFORMATION           = $0020;
  THREAD_QUERY_INFORMATION         = $0040;
  THREAD_SET_THREAD_TOKEN          = $0080;
  THREAD_IMPERSONATE               = $0100;
  THREAD_DIRECT_IMPERSONATION      = $0200;
  THREAD_SET_LIMITED_INFORMATION   = $0400;
  THREAD_QUERY_LIMITED_INFORMATION = $0800;
  THREAD_ALL_ACCESS                = STANDARD_RIGHTS_REQUIRED or SYNCHRONIZE or $03FF;

function OpenThread(dwDesiredAccess: DWord;
                    bInheritHandle: Bool;
                    dwThreadId: DWord): DWord; stdcall; external 'kernel32.dll';


procedure TForm1.Button1Click(Sender: TObject);
var iii:integer;
    handle:thandle;
    creationtime,exittime,kerneltime,usertime:filetime;
begin
  Handle:=OpenThread(THREAD_SET_INFORMATION or THREAD_QUERY_INFORMATION, False, windows.GetCurrentThreadId);
  if handle<>0 then
  begin
    getthreadtimes(Handle,creationtime,exittime,kerneltime,usertime);
    label1.caption:='Total time for Thread #'+inttostr(windows.GetCurrentThreadId)+': '+inttostr( (int64(kerneltime)+int64(usertime)) div 1000 )+' msec';
    CloseHandle(Handle);
  end;
end;

#5


4  

Using "GetThreadTimes"? If you measure the time between calls to "GetThreadTimes" and store the previous user and/or kernel times then you know how much time the thread has had since you last checked. You also know how much time has elapsed in the mean time and thus you can work out how much CPU time was used. It would be best (for timer resolution reasons) to make this check every second or so and work out its average CPU usage over that second.

使用“GetThreadTimes”?如果您测量调用“GetThreadTimes”并存储先前用户和/或内核时间之间的时间,那么您就知道自上次检查以来线程已经有多长时间了。您还知道平均时间已经过了多少时间,因此您可以计算出使用了多少CPU时间。最好(出于计时器分辨率的原因)每隔一秒左右进行一次检查,并计算出其平均CPU使用率。

#6


1  

Here is a simple WMI query wrapper. With help of it you can call this to get data:

这是一个简单的WMI查询包装器。借助它,您可以调用它来获取数据:

getWmiQueryResult(L"SELECT PercentProcessorTime FROM Win32_PerfRawData_PerfProc_Thread WHERE IdProcess=4 and IdThread=8", L"PercentProcessorTime ");

Also you might want to look at the Win32_PerfRawData_PerfProc_Thread documentation to see what other properties you can fetch.

您还可以查看Win32_PerfRawData_PerfProc_Thread文档,了解您可以获取的其他属性。