我要每3秒取一次设置好的几个进程的CPU点用率,网上找了一个例子,取一个进程得到的CPU利用率结果正常(和任务管理器里显示的数据一样),可是同时取多个进程的CPU率得到的结果都是错误的,这是什么原因?同时执行这个函数会有什么共享冲突吗?
int GetCpuUsage(DWORD pID) //传入进程ID,返回CPU利用率
{
int cpuusage;
PVOID pProcInfo = NULL;
DWORD dwInfoSize = 0x20000;
PPROCESSINFO pProcessInfo;
DWORD dwWorkingSet;
long ( __stdcall *NtQuerySystemInformation )( DWORD, PVOID, DWORD, DWORD ); static __int64 LastTotalProcessCPUUsage = 0;
static __int64 LastCurrentProcessCPUUsage = 0;
int CurrentDelta;
int TotalDelta;
__int64 TotalProcessCPUUsage = 0;
__int64 CurrentProcessCPUUsage = 0;
/////////////////////////////////
pProcInfo = (PVOID)(new byte[dwInfoSize]);
NtQuerySystemInformation = (long(__stdcall*)(DWORD,PVOID,DWORD,DWORD))
GetProcAddress( GetModuleHandle( "ntdll.dll" ),"NtQuerySystemInformation" );
NtQuerySystemInformation(5,pProcInfo,dwInfoSize,0);
pProcessInfo = (PPROCESSINFO)pProcInfo;
do
{
TotalProcessCPUUsage += (__int64)pProcessInfo->KernelTime.QuadPart + (__int64)pProcessInfo->UserTime.QuadPart;
if(pProcessInfo->dwProcessID == pID)
{
dwWorkingSet = pProcessInfo->dwWorkingSet;
CurrentProcessCPUUsage += (__int64)pProcessInfo->KernelTime.QuadPart + (__int64)pProcessInfo->UserTime.QuadPart;
}
/////////
if(pProcessInfo->dwOffset == 0)
{
break;
}
pProcessInfo = (PPROCESSINFO)((byte*)pProcessInfo + pProcessInfo->dwOffset);
}
while(true);
TotalDelta = TotalProcessCPUUsage - LastTotalProcessCPUUsage;
CurrentDelta = CurrentProcessCPUUsage - LastCurrentProcessCPUUsage;
if(TotalDelta != 0)
cpuusage = 100 * CurrentDelta / TotalDelta;
//this->Caption = "CPU = " + IntToStr(100 * CurrentDelta / TotalDelta) +
//"Memory = "+ IntToStr(dwWorkingSet / 1024) " K";
LastTotalProcessCPUUsage = TotalProcessCPUUsage;
LastCurrentProcessCPUUsage = CurrentProcessCPUUsage;
delete[] pProcInfo;
return cpuusage;}
int GetCpuUsage(DWORD pID) //传入进程ID,返回CPU利用率
{
int cpuusage;
PVOID pProcInfo = NULL;
DWORD dwInfoSize = 0x20000;
PPROCESSINFO pProcessInfo;
DWORD dwWorkingSet;
long ( __stdcall *NtQuerySystemInformation )( DWORD, PVOID, DWORD, DWORD ); static __int64 LastTotalProcessCPUUsage = 0;
static __int64 LastCurrentProcessCPUUsage = 0;
int CurrentDelta;
int TotalDelta;
__int64 TotalProcessCPUUsage = 0;
__int64 CurrentProcessCPUUsage = 0;
/////////////////////////////////
pProcInfo = (PVOID)(new byte[dwInfoSize]);
NtQuerySystemInformation = (long(__stdcall*)(DWORD,PVOID,DWORD,DWORD))
GetProcAddress( GetModuleHandle( "ntdll.dll" ),"NtQuerySystemInformation" );
NtQuerySystemInformation(5,pProcInfo,dwInfoSize,0);
pProcessInfo = (PPROCESSINFO)pProcInfo;
do
{
TotalProcessCPUUsage += (__int64)pProcessInfo->KernelTime.QuadPart + (__int64)pProcessInfo->UserTime.QuadPart;
if(pProcessInfo->dwProcessID == pID)
{
dwWorkingSet = pProcessInfo->dwWorkingSet;
CurrentProcessCPUUsage += (__int64)pProcessInfo->KernelTime.QuadPart + (__int64)pProcessInfo->UserTime.QuadPart;
}
/////////
if(pProcessInfo->dwOffset == 0)
{
break;
}
pProcessInfo = (PPROCESSINFO)((byte*)pProcessInfo + pProcessInfo->dwOffset);
}
while(true);
TotalDelta = TotalProcessCPUUsage - LastTotalProcessCPUUsage;
CurrentDelta = CurrentProcessCPUUsage - LastCurrentProcessCPUUsage;
if(TotalDelta != 0)
cpuusage = 100 * CurrentDelta / TotalDelta;
//this->Caption = "CPU = " + IntToStr(100 * CurrentDelta / TotalDelta) +
//"Memory = "+ IntToStr(dwWorkingSet / 1024) " K";
LastTotalProcessCPUUsage = TotalProcessCPUUsage;
LastCurrentProcessCPUUsage = CurrentProcessCPUUsage;
delete[] pProcInfo;
return cpuusage;}
当然也就只有一个进程可以有cpu占用率吧。
猜的。
class GetCPUPercentage
...{
private:
CRITICAL_SECTION cs; // 供多线程同步的临界区变量
HANDLE hd; // 空闲进程的句柄
DWORD t1; // 时间戳
int percent; // 最近一次计算的CPU占用率 __int64 oldp;
__int64 FileTimeToInt64(const FILETIME& time);
int GetTime(__int64& proc); // 得到进程占用的CPU时间
public:
GetCPUPercentage();
~GetCPUPercentage(); int Get(); // 得到CPU占用率
};GetCPUPercentage::GetCPUPercentage()
...{
InitializeCriticalSection(&cs); // 初始化线程临界区变量 percent = 0; // 初始的占用率 DWORD pid = GetCurrentProcessId(); // 得到当前进程id
hd = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid); // 通过id得到进程的句柄
if( hd==NULL )...{
return;
} // 得到初始时刻的值
GetTime(oldp);
t1 = GetTickCount();
}GetCPUPercentage::~GetCPUPercentage()
...{
if( hd!=NULL )...{
CloseHandle(hd);
}
DeleteCriticalSection(&cs);
}// 时间格式转换
__int64 GetCPUPercentage::FileTimeToInt64(const FILETIME& time)
...{
ULARGE_INTEGER tt;
tt.LowPart = time.dwLowDateTime;
tt.HighPart = time.dwHighDateTime;
return(tt.QuadPart);
}// 得到进程占用的CPU时间
int GetCPUPercentage::GetTime(__int64& proc)
...{
FILETIME create;
FILETIME exit;
FILETIME ker; // 内核占用时间
FILETIME user; // 用户占用时间
FILETIME now;
if( !GetProcessTimes(hd, &create, &exit, &ker, &user) )...{
return(-1);
} proc = (FileTimeToInt64(ker) + FileTimeToInt64(user))/10000;
return(0);
}// 进行换算
int GetCPUPercentage::Get()
...{
if( hd==NULL )
return(0); EnterCriticalSection(&cs);
DWORD t2 = GetTickCount();
DWORD dt = t2 - t1;
if( dt>139 )...{ // 毫秒数。用一个比较少的时间片作为计算单位,这个值可修改
__int64 proc;
GetTime(proc); percent = ((proc-oldp)*100)/dt; t1 = t2;
oldp = proc;
}
LeaveCriticalSection(&cs);
return(percent);
}// 定义一个全局变量
GetCPUPercentage _cpu;// 下面是用C++Bulider写的测试例子:
// --------------------------
// 在用一个时钟不停地显示当前的CPU占用率
void __fastcall TForm1::Timer1Timer(TObject *Sender)
...{
Label1->Caption = _cpu.Get();
}//---------------------------------------------------------------------------
// 再弄个按钮
LRESULT WINAPI TestThread(LONG lParam)
...{
int n = lParam;
for(int i=0 ;i<n; i++)...{
Form1->Label2->Caption = i;
Sleep(12);
}
return(0);
}
// 点击这个按钮会创建一些线程来把CPU整的繁忙些
void __fastcall TForm1::Button1Click(TObject *Sender)
...{
int n = atoi(Edit1->Text.c_str());
DWORD dwThreadid;
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)TestThread,
(void*)n, 0, &dwThreadid);
}文章出处:http://www.diybl.com/course/3_program/c++/cppsl/2008516/117032.html
HQUERY hQuery;
PDH_STATUS pdhStatus = PdhOpenQuery(0, 0, &hQuery);
HCOUNTER pCounterHandle;
PDH_FMT_COUNTERVALUE fmtValue;
DWORD dwctrType;
pdhStatus = PdhAddCounter(hQuery, _TEXT("\\Process(进程名)\\% Processor Time"), 0, &pCounterHandle);
pdhStatus = PdhCollectQueryData(hQuery);
Sleep(1000);
pdhStatus = PdhCollectQueryData(hQuery);
pdhStatus = PdhGetFormattedCounterValue(pCounterHandle, PDH_FMT_DOUBLE, &dwctrType, &fmtValue);
pdhStatus = PdhCloseQuery(hQuery);
fmtValue.doubleValue