|
Yes.
There is '% processor time' counter under 'process' object whose index is 230.
The class CPerfCounters retrieves any counter that you want for any instance.
Therefore, for your case you set:
dwObjectIndex = 230
dwCpuUsageIndex = 6 // '% processor time' counter
szInstance = "the process name" (as it appears in the TaskManager).
Thats all.
|
|
|
|
|
hi ,
where can i find this class CPerfCounters ?
The process's cpu usage refers to the "effort" of the cpu while running this process and not to the running time inside the processor.
tnx for your help
Dvir
|
|
|
|
|
I believe that you have downloaded my sample.
I wrote a generic template class ,called CPerfCounters in PerfCounters.h , which gets a counter value for a specific object index and for an instance name.
The class CPerfCounters is a template since performance counters are of different size ,such as 4 bytes or 8 bytes.
Take a look at GetCpuUsage() function which uses CPerfCounters class, and do what i wrote in the previous reply.
|
|
|
|
|
Hi,
I also have this problem.
I have changed: dwObjectIndex = 230;
dwCpuUsageIndex = 6;
strcpy(szInstance,"EXCEL.EXE"); (also "EXEL")
and GetCpuUsage always returns Total Cpu usage.
Thank you for your help.
Pavel
|
|
|
|
|
You are both right. I fixed that bug.
I have posted updates that enable getting cpu usage for a specific process.
There is also sample fucntion for that.
You can download it now.
|
|
|
|
|
That's great, thanx for your help.
I have tested the update, but sometimes GetCpuUsage returns number greater then 100 %.
But for my purpose doesn't really matter.
Pavel
|
|
|
|
|
Hi Dvir,
I have posted updates that enable getting cpu usage for a specific process.
There is also sample function for that.
You can download it now.
|
|
|
|
|
Me think, this is simplier:
__int64 creation0, exit0, kernel0, user0;
DWORD ticks0 = 0L;
// at some place in the code
GetProcessTimes( GetCurrentProcess( ),
( LPFILETIME )&creation0,
( LPFILETIME )&exit0,
( LPFILETIME )&kernel0,
( LPFILETIME )&user0 );
ticks0 = GetTickCount( );
....
.... Do something usefull here or just Sleep for at least a second...
....
DWORD ticks = GetTickCount( );
__int64 creation, exit, kernel, user;
GetProcessTimes( GetCurrentProcess( ),
( LPFILETIME )&creation,
( LPFILETIME )&exit,
( LPFILETIME )&kernel,
( LPFILETIME )&user );
// a little math
__int64 total = ( kernel + user - kernel0 - user0 ) / 10000;
UINT nUsagePercent = int( double( total ) * 100 / (ticks - ticks0 );
Am I wrong?...
|
|
|
|
|
The GetProcessTimes function retrieves timing information for the specified process. It doesn't return the system-wide cpu usage.
Through the performance counter , you get system-wide cpu usage.
Furthermore, i executed your sample and i always get 0.
|
|
|
|
|
Works great for me.. thanks for the code snippet
Cheers, Marc Click to see my *real* signature
|
|
|
|
|
Great, I implemented it, but I cannot get values more precise than 1/100 sec of the kernel time and user time of the processes. What am I doing wrong?
thx, DA
|
|
|
|
|
This seems to work fine, but you might have to divide the result by the number of CPUs present in the system.
|
|
|
|
|
the function is following:
double GetCpuUsage(LPCTSTR pProcessName)
{
__int64 creation0, exit0, kernel0, user0;
DWORD ticks0 = 0L;
// at some place in the code
GetProcessTimes( GetCurrentProcess(),
( LPFILETIME )&creation0,
( LPFILETIME )&exit0,
( LPFILETIME )&kernel0,
( LPFILETIME )&user0 );
ticks0 = GetTickCount( );
// Do something usefull here or just Sleep for at least a second
Sleep(10000);
DWORD ticks = GetTickCount( );
__int64 creation, exit, kernel, user;
GetProcessTimes( GetCurrentProcess( ),
( LPFILETIME )&creation,
( LPFILETIME )&exit,
( LPFILETIME )&kernel,
( LPFILETIME )&user );
// a little math
printf("kernel0=%ld\n",kernel0);
printf("kernel= %ld\n",kernel);
printf("user0=%ld\n",user0);
printf("user= %ld\n",user);
printf("kernel0+user0=%ld",kernel0+user0);
printf("kernel+user=%ld",kernel+user);
__int64 total = ( kernel + user - kernel0 - user0 ) / 10000;
double nUsagePercent = double( double( total ) * 100 / (ticks - ticks0 ));
return nUsagePercent;
}
how were you do it? thanks!
|
|
|
|
|
the function is following:
int GetCpuUsage(LPCTSTR pProcessName)
{
__int64 creation0, exit0, kernel0, user0;
DWORD ticks0 = 0L;
// at some place in the code
GetProcessTimes( GetCurrentProcess(),
( LPFILETIME )&creation0,
( LPFILETIME )&exit0,
( LPFILETIME )&kernel0,
( LPFILETIME )&user0 );
ticks0 = GetTickCount( );
// Do something usefull here or just Sleep for at least a second
Sleep(10000);
DWORD ticks = GetTickCount( );
__int64 creation, exit, kernel, user;
GetProcessTimes( GetCurrentProcess( ),
( LPFILETIME )&creation,
( LPFILETIME )&exit,
( LPFILETIME )&kernel,
( LPFILETIME )&user );
// a little math
printf("kernel0=%ld\n",kernel0);
printf("kernel= %ld\n",kernel);
printf("user0=%ld\n",user0);
printf("user= %ld\n",user);
printf("kernel0+user0=%ld",kernel0+user0);
printf("kernel+user=%ld",kernel+user);
__int64 total = ( kernel + user - kernel0 - user0 ) / 10000;
int nUsagePercent = int( double( total ) * 100 / (ticks - ticks0 ));
return nUsagePercent;
}
how did you do it? thanks!
|
|
|
|
|
i think the original code was very good, but perhaps a bit mis-leading.
you need to use some persistence to store the original reference values between calls to get the cpu usage. these reference values require resettting everytime you read the cpu usage.
if you're using c++, you can wrap it up in a class (this may not compile, but it shows you roughly what you need to do):
with the following, create an object perf::cpu_monitor in your application.
then periodically (e.g. on a Windows timer event), poll the cpu usage. i poll for this value once per second.
this works fine on my Windows 2000, dual CPU system - it will tell you the CPU usage of the process that you are running and matches very well with Task Manager.
hope this helps.
Dan
// wrapped up into a class by dan hill, july 2003
#ifndef CPU_USAGE_HPP_INCLUDED
#define CPU_USAGE_HPP_INCLUDED
#pragma once
#pragma warning( disable : 4251 4503 4786 )
#include "windows.h"
namespace perf
{
class cpu_monitor
{
private:
struct perf_data
{
__int64 creation0,
exit0,
kernel0,
user0;
DWORD ticks0;
};
public:
// constructor:
cpu_monitor()
{
::GetSystemInfo(&m_system_info);
init_perf_data();
};
// poll cpu usage:
UINT get_cpu_usage()
{
const DWORD ticks = ::GetTickCount( );
__int64 creation, exit, kernel, user;
::GetProcessTimes (
::GetCurrentProcess(),
(LPFILETIME)&creation,
(LPFILETIME)&exit,
(LPFILETIME)&kernel,
(LPFILETIME)&user
);
// a little math
const __int64 total = ( kernel + user - m_perf_data.kernel0 - m_perf_data.user0 ) / 10000;
const DWORD tick_difference (ticks - m_perf_data.ticks0);
// since tick count wraps every 49.7 days:
UINT nUsagePercent (0);
if (tick_difference)
{
nUsagePercent = int( double( total / m_system_info.dwNumberOfProcessors ) * 100 / (tick_difference));
}
init_perf_data();
return nUsagePercent;
};
private:
void init_perf_data()
{
::GetProcessTimes (
GetCurrentProcess(),
(LPFILETIME)&m_perf_data.creation0,
(LPFILETIME)&m_perf_data.exit0,
(LPFILETIME)&m_perf_data.kernel0,
(LPFILETIME)&m_perf_data.user0
);
m_perf_data.ticks0 = GetTickCount();
};
private:
perf_data m_perf_data;
SYSTEM_INFO m_system_info;
};
}
#endif // ndef CPU_USAGE_HPP_INCLUDED
|
|
|
|
|
PS The MSDN states that ::GetProcessTimes works on the following operating systems:
Client: Included in Windows XP, Windows 2000 Professional, and Windows NT Workstation 3.5 and later.
Server: Included in Windows Server 2003, Windows 2000 Server, and Windows NT Server 3.5 and later.
This indicates that it won't work on Windows 95, 98, ME etc.
|
|
|
|
|
"nUsagePercent = int( double( total / m_system_info.dwNumberOfProcessors ) * 100 / (tick_difference));" in the function of get_cpu_usage
why did you divide m_system_info.dwNumberOfProcessors?
Thanks!
|
|
|
|
|
get_cpu_usage() only can get the cpuage of the process that the function among?
Would you like to give me a way to get handle of process through process *.exe. Then we can get cpuage of any processes.
|
|
|
|
|
The OS API call ::GetProcessTimes(...) requires as a first parameter: (quote from MSDN):
HANDLE hProcess
[in] Handle to the process whose timing information is sought. This handle must be created with the PROCESS_QUERY_INFORMATION access right.
If you can find a way of abtaining the handle to another process, then you should modify the class i gave you to take the HANDLE in its constructor and store it as a member,
e.g.
// Constructor becomes:
cpu_monitor(const HANDLE h_process)
:
m_hProcess (h_process)
{
::GetSystemInfo(&m_system_info);
init_perf_data();
};
// add to member variables:
private:
const HANDLE m_hProcess;
and then replace calls to ::GetProcess() with this m_hProcess in the class functions.
::GetProcessTimes(m_hProcess, ...
...
);
How you get this handle: I am not sure what API calls are provided to aid you here. Try searching the MSDN or other online resources. There may be some level of operating system security restricting you from obtaining it from other processes, I do not know.
Hope this helps
|
|
|
|
|
|
I divided by the number of processors from experimentation.
I am developing process containing multiple threads. My target machines consist of either 1 or 2 CPUs.
When I tried the code without dividing by the number of threads, the CPU usage reported was double the value reported by Task Manager on the 2 CPU machine. When I ran the same process on a single CPU machine, the number was correct. Hence the reason for dividing by the number of processors.
|
|
|
|
|
I found that thread almost 2 years after I originally posted message here.
Funy how my original code was interpreted.
I agree, it was "a bit mis-leading".
I thought you guys will figure out that the function I was talking about should be constantly running on a different thread.
If done like that and that function is constantly running -- your main application thread will get processor usage at any time by checking some static variable holding that value...
Regards
"...Ability to type is not enough to become a Programmer. Unless you type in VB. But then again you have to type really fast..."
Me
|
|
|
|
|
On my Windows XP machine it always shows 100%. Strange.
|
|
|
|
|
You are right. It seems to be the same in Windows XP.
I checked it only on Windows NT4.
Article Q259390 in MSDN tells that some counters have been moved in Windows 2000.
One of them is 'System\% Total Processor Time' that was moved to Processor Performance object.
Therefore, on Win2K i should check 'Processor(_Total)\% Processor Time' .
I will update the code to support Win2K.
|
|
|
|
|
Article Q259390 in MSDN tells that some counters have been moved in Windows 2000.
One of them is 'System\% Total Processor Time' that was moved to Processor Performance object.
Therefore, on Win2K i should check 'Processor(_Total)\% Processor Time' .
I will update the code to support Win2K.
I think that Windows XP is like win2K, so the changes that i will do, will
be good for XP, as well.
|
|
|
|
|