代码
cpuload.h
#pragma once
#include <iostream>
#include <vector>
#ifndef WIN32
class CPUData {
public:
void ReadData(const std::string &line);
std::size_t GetActiveTime() const;
std::size_t GetIdleTime() const;
std::size_t GetStateTime(unsigned int state) const;
std::size_t GetTotalTime() const;
const std::string &GetLabel() const;
public:
static bool IsDataCPUStats(const std::string &line);
public:
enum CPUStates {
S_USER = 0,
S_NICE,
S_SYSTEM,
S_IDLE,
S_IOWAIT,
S_IRQ,
S_SOFTIRQ,
S_STEAL,
S_GUEST,
S_GUEST_NICE,
NUM_CPU_STATES
};
private:
static const std::string STR_CPU;
static const std::string STR_TOT;
static const std::size_t LEN_STR_CPU;
private:
std::string mLabel;
std::size_t mTimes[NUM_CPU_STATES];
};
inline std::size_t CPUData::GetActiveTime() const {
return mTimes[S_USER] + mTimes[S_NICE] + mTimes[S_SYSTEM] + mTimes[S_IRQ] +
mTimes[S_SOFTIRQ] + mTimes[S_STEAL] + mTimes[S_GUEST] +
mTimes[S_GUEST_NICE];
}
inline std::size_t CPUData::GetIdleTime() const {
return mTimes[S_IDLE] + mTimes[S_IOWAIT];
}
inline std::size_t CPUData::GetStateTime(unsigned int state) const {
if (state < NUM_CPU_STATES)
return mTimes[state];
else
return 0;
}
inline std::size_t CPUData::GetTotalTime() const {
return mTimes[S_USER] + mTimes[S_NICE] + mTimes[S_SYSTEM] + mTimes[S_IDLE] +
mTimes[S_IOWAIT] + mTimes[S_IRQ] + mTimes[S_SOFTIRQ] +
mTimes[S_STEAL] + mTimes[S_GUEST] + mTimes[S_GUEST_NICE];
}
inline const std::string &CPUData::GetLabel() const { return mLabel; }
inline bool CPUData::IsDataCPUStats(const std::string &line) {
return (!line.compare(0, LEN_STR_CPU, STR_CPU));
}
class CPUSnapshot {
public:
CPUSnapshot();
std::size_t GetNumEntries() const;
const char *GetLabelTotal() const;
const char *GetLabel(unsigned int cpu) const;
std::size_t GetActiveTimeTotal() const;
std::size_t GetActiveTime(unsigned int cpu) const;
std::size_t GetIdleTimeTotal() const;
std::size_t GetIdleTime(unsigned int cpu) const;
std::size_t GetStateTimeTotal(unsigned int state) const;
std::size_t GetStateTime(unsigned int state, unsigned int cpu) const;
std::size_t GetTotalTimeTotal() const;
std::size_t GetTotalTime(unsigned int cpu) const;
private:
static const int INDEX_TOT;
private:
std::vector<CPUData> mEntries;
};
inline std::size_t CPUSnapshot::GetNumEntries() const {
return mEntries.size() - 1;
}
inline const char *CPUSnapshot::GetLabelTotal() const {
return mEntries[INDEX_TOT].GetLabel().c_str();
}
inline const char *CPUSnapshot::GetLabel(unsigned int cpu) const {
// skip total
++cpu;
if (cpu < mEntries.size())
return mEntries[cpu].GetLabel().c_str();
else
return NULL;
}
inline std::size_t CPUSnapshot::GetActiveTimeTotal() const {
return mEntries[INDEX_TOT].GetActiveTime();
}
inline std::size_t CPUSnapshot::GetActiveTime(unsigned int cpu) const {
// skip total
++cpu;
if (cpu < mEntries.size())
return mEntries[cpu].GetActiveTime();
else
return 0;
}
inline std::size_t CPUSnapshot::GetIdleTimeTotal() const {
return mEntries[INDEX_TOT].GetIdleTime();
}
inline std::size_t CPUSnapshot::GetIdleTime(unsigned int cpu) const {
// skip total
++cpu;
if (cpu < mEntries.size())
return mEntries[cpu].GetIdleTime();
else
return 0;
}
inline std::size_t CPUSnapshot::GetStateTimeTotal(unsigned int state) const {
return mEntries[INDEX_TOT].GetStateTime(state);
}
inline std::size_t CPUSnapshot::GetStateTime(unsigned int state,
unsigned int cpu) const {
// skip total
++cpu;
if (cpu < mEntries.size())
return mEntries[cpu].GetStateTime(state);
else
return 0;
}
inline std::size_t CPUSnapshot::GetTotalTimeTotal() const {
return mEntries[INDEX_TOT].GetTotalTime();
}
inline std::size_t CPUSnapshot::GetTotalTime(unsigned int cpu) const {
// skip total
++cpu;
if (cpu < mEntries.size())
return mEntries[cpu].GetTotalTime();
else
return 0;
}
#endif
class LoadMnger {
public:
~LoadMnger();
static LoadMnger *instance();
double GetCpuUsage();
private:
LoadMnger();
static LoadMnger *m_instance;
#ifdef WIN32
unsigned long long m_ullLastTime;
unsigned long long m_ullLastIdleTime;
#else
size_t m_ullLastTime;
size_t m_ullLastIdleTime;
#endif
};
cpuload.cpp
#include "LoadManager.h"
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#ifdef WIN32
#include <windows.h>
#else
using namespace std;
const std::string CPUData::STR_CPU("cpu");
const std::string CPUData::STR_TOT("tot");
const std::size_t CPUData::LEN_STR_CPU = 3;
const int CPUSnapshot::INDEX_TOT = 0;
#endif
LoadMnger *LoadMnger::m_instance = NULL;
LoadMnger::LoadMnger() {
GetCpuUsage();
}
LoadMnger::~LoadMnger() {}
LoadMnger *LoadMnger::instance() {
if (!m_instance)
m_instance = new LoadMnger();
return m_instance;
}
#ifdef WIN32
unsigned long long __FileTime2Utc(const FILETIME &ft) {
LARGE_INTEGER li;
li.LowPart = ft.dwLowDateTime;
li.HighPart = ft.dwHighDateTime;
return li.QuadPart;
}
double LoadMnger::GetCpuUsage() {
FILETIME idleTime, kernelTime, userTime;
if (!GetSystemTimes(&idleTime, &kernelTime, &userTime)) {
printf("GetSystemTimes", GetLastError());
return -1;
}
unsigned long long _time =
__FileTime2Utc(kernelTime) + __FileTime2Utc(userTime),
_idle_time = __FileTime2Utc(idleTime);
if (!m_ullLastTime || !m_ullLastIdleTime) {
m_ullLastIdleTime = _idle_time;
m_ullLastTime = _time;
return -1;
}
unsigned long long idle = _idle_time - m_ullLastIdleTime,
usage = _time - m_ullLastTime;
m_ullLastIdleTime = _idle_time;
m_ullLastTime = _time;
if (!usage)
return -1;
return (usage - idle) * 100.0 / usage;
}
#else
double LoadMnger::GetCpuUsage() {
CPUSnapshot Csp;
size_t curacTime = Csp.GetActiveTimeTotal();
size_t curidlTIme = Csp.GetIdleTimeTotal();
const float ACTIVE_TIME = curacTime - m_ullLastTime;
const float IDLE_TIME = curidlTIme - m_ullLastIdleTime;
const float TOTAL_TIME = ACTIVE_TIME + IDLE_TIME;
m_ullLastTime = curacTime;
m_ullLastIdleTime = curidlTIme;
return 100.f * ACTIVE_TIME / TOTAL_TIME;
}
// == PUBLIC FUNCTIONS ==
CPUSnapshot::CPUSnapshot() {
std::ifstream fileStat("/proc/stat");
std::string line;
while (std::getline(fileStat, line)) {
// cpu stats line found
if (CPUData::IsDataCPUStats(line)) {
// store entry
mEntries.push_back(CPUData());
CPUData &entry = mEntries.back();
entry.ReadData(line);
}
}
}
// == PUBLIC FUNCTIONS ==
void CPUData::ReadData(const std::string &line) {
std::istringstream ss(line);
// read cpu label
ss >> mLabel;
// remove "cpu" from the label when it's a processor number
if (mLabel.size() > LEN_STR_CPU)
mLabel.erase(0, LEN_STR_CPU);
// replace "cpu" with "tot" when it's total values
else
mLabel = STR_TOT;
// read times
for (int i = 0; i < NUM_CPU_STATES; ++i) {
ss >> mTimes[i];
}
}
#endif
main.cpp
#include "LoadManager.h"
#include <iostream>
#include <string>
#ifdef WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
using namespace std;
int main() {
LoadMnger *mng = LoadMnger::instance();
while (1) {
//如果时间间隔太短会计算失败,具体可以看GetCpuUsage()中GetSystemTimes获取的结果
#ifdef WIN32
Sleep(1000);
#else
sleep(1);
#endif
double usage = mng->GetCpuUsage();
cout << "main: " << usage << endl;
}
return 0;
}
代码是参考大佬的代码合并、修改而来,如有侵权,请私信删除。
部分源码来自:
https://github.com/vivaladav/cpu-stat
https://github.com/mewiteor/MonitorBar