|
I'm using XP Pro SP1 and it works fine for me now. Check my reply to the 100% thread to see why.
|
|
|
|
|
Hello,
I am writing a code to display Cpu Usage on machines running win NT/2000/95/98.
Thanks for the information on getting CPU usage on win NT/2000.
How to get CPU usage on Win 95/98 machines?
Thanks
Madhu
|
|
|
|
|
Performance counters in Win9x are totally different from winNT/2K/XP.
For win95 read "HOWTO: Access the Performance Registry Under Windows 95" Q174631 in MSDN.
|
|
|
|
|
Hi
Thanks for ur help.
Madhu
|
|
|
|
|
Hi,
is there a simple way to find the cpu usage of a specific process (assuming few processes use the processor simultaneously) ?
thx,
Dvir
|
|
|
|
|
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
|
|
|
|
|
|