例子:
PID=0,缺省为当前进程,但最好是获取当前进程ID传递进去,当然也可以选择其它进程的ID。
PerformanceCounter pc;
pc.Open(0, "//Processor(_Total)//% Processor Time");
源实现:
#include <windows.h>
#include <pdh.h>
class PerformanceCounter
{
public:
PerformanceCounter() noexcept;
virtual ~PerformanceCounter() noexcept;
public:
virtual double Next() noexcept;
virtual void Open(int pid, LPCSTR counter);
virtual void Dispose() noexcept;
private:
void Release() noexcept;
private:
std::atomic<void*> m_phQuery = NULL;
std::atomic<void*> m_phCounter = NULL;
};
PerformanceCounter::PerformanceCounter() noexcept
: m_phQuery(NULL)
, m_phCounter(NULL)
{
}
PerformanceCounter::~PerformanceCounter() noexcept
{
Release();
}
void PerformanceCounter::Open(int pid, LPCSTR counter)
{
void* phQuery = NULL;
if (PdhOpenQueryA(NULL, pid, &phQuery) != ERROR_SUCCESS)
{
throw std::exception("The handle to the PerformanceCounter could not be opened.");
}
void* phCounter = NULL;
if (PdhAddCounterA(phQuery, counter, 0, &phCounter) != ERROR_SUCCESS)
{
PdhCloseQuery(phCounter);
throw std::exception("Unable to add a performance counter instance.");
}
else
{
Release();
}
m_phQuery.exchange(phQuery);
m_phCounter.exchange(phCounter);
}
double PerformanceCounter::Next() noexcept
{
if (m_phQuery == NULL)
{
return 0;
}
else
{
PdhCollectQueryData(m_phQuery);
}
PDH_FMT_COUNTERVALUE counterValue;
if (PdhGetFormattedCounterValue(m_phCounter, PDH_FMT_DOUBLE, NULL, &counterValue) == ERROR_SUCCESS)
{
return counterValue.doubleValue;
}
return 0;
}
void PerformanceCounter::Dispose() noexcept
{
Release();
}
void PerformanceCounter::Release() noexcept
{
void* phCounter = m_phCounter.exchange(NULL);
if (NULL != phCounter)
{
PdhRemoveCounter(phCounter);
}
void* phQuery = m_phQuery.exchange(NULL);
if (phQuery != NULL)
{
PdhCloseQuery(phQuery);
}
}