本文的代码地址:https://github.com/BlueLeen/cpu_and_mem_monitor.git,代码已经在ubuntu18.04系统上编译通过,能够高效准确检测cpu、内存指标。
代码编译的详细步骤:
$ git clone https://github.com/BlueLeen/cpu_and_mem_monitor.git
$ cd cpu_and_mem_monitor
$ mkdir _build
$ cd _build
$ cmake ..
$ make
1、CPU使用率
主要是读取/proc/stat文件相关信息,进行解析。部分源代码如下:
#ifndef PROCDIR
#define PROCDIR "/proc"
#endif
#ifndef PROCSTATFILE
#define PROCSTATFILE PROCDIR "/stat"
#endif
bool CPUStats::UpdateCPUData()
{
unsigned long long int usertime, nicetime, systemtime, idletime;
unsigned long long int ioWait, irq, softIrq, steal, guest, guestnice;
int cpuid = -1;
if (!m_inited)
return false;
std::string line;
std::ifstream file (PROCSTATFILE);
bool ret = false;
if (!file.is_open()) {
std::cerr << "Failed to opening " << PROCSTATFILE << std::endl;
return false;
}
do {
if (!std::getline(file, line)) {
break;
} else if (!ret && sscanf(line.c_str(), "cpu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu",
&usertime, &nicetime, &systemtime, &idletime, &ioWait, &irq, &softIrq, &steal, &guest, &guestnice) == 10) {
ret = true;
calculateCPUData(m_cpuDataTotal, usertime, nicetime, systemtime, idletime, ioWait, irq, softIrq, steal, guest, guestnice);
} else if (sscanf(line.c_str(), "cpu%4d %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu",
&cpuid, &usertime, &nicetime, &systemtime, &idletime, &ioWait, &irq, &softIrq, &steal, &guest, &guestnice) == 11) {
//std::cerr << "Parsing 'cpu" << cpuid << "' line:" << line << std::endl;
if (!ret) {
//std::cerr << "Failed to parse 'cpu' line" << std::endl;
std::cerr << "Failed to parse 'cpu' line:" << line << std::endl;
return false;
}
if (cpuid < 0 /* can it? */ || (size_t)cpuid > m_cpuData.size()) {
std::cerr << "Cpu id '" << cpuid << "' is out of bounds" << std::endl;
return false;
}
CPUData& cpuData = m_cpuData[cpuid];
calculateCPUData(cpuData, usertime, nicetime, systemtime, idletime, ioWait, irq, softIrq, steal, guest, guestnice);
cpuid = -1;
} else {
break;
}
} while(true);
m_cpuPeriod = (double)m_cpuData[0].totalPeriod / m_cpuData.size();
m_updatedCPUs = true;
return ret;
}
2、CPU温度
安装相关库:
$ sudo apt install lm-sensors libsensors4-dev
部分源代码如下:
void LMSensor::_update_feature_temp()
{
const sensors_subfeature *sf;
/*
* If the sensor is reporting a fault, we can't trust anything else
* it might tell us. Keep previous/default values.
*/
sf = sensors_get_subfeature(&m_name, &m_feature, SENSORS_SUBFEATURE_TEMP_FAULT);
if (sf && _get_value(sf))
return;
sf = sensors_get_subfeature(&m_name, &m_feature, SENSORS_SUBFEATURE_TEMP_INPUT);
m_value = sf ? _get_value(sf) : 0.0;
sf = sensors_get_subfeature(&m_name, &m_feature, SENSORS_SUBFEATURE_TEMP_ALARM);
m_alarm = sf && _get_value(sf);
sf = sensors_get_subfeature(&m_name, &m_feature, SENSORS_SUBFEATURE_TEMP_MAX_ALARM);
m_alarm |= sf && _get_value(sf);
sf = sensors_get_subfeature(&m_name, &m_feature, SENSORS_SUBFEATURE_TEMP_MIN_ALARM);
m_alarm |= sf && _get_value(sf);
}
3、内存使用率
部分源代码如下:
void update_meminfo(void) {
FILE *meminfo_fp;
static int reported = 0;
/* unsigned int a; */
char buf[256];
/* With multi-threading, calculations that require
* multple steps to reach a final result can cause havok
* if the intermediary calculations are directly assigned to the
* information struct (they may be read by other functions in the meantime).
* These variables keep the calculations local to the function and finish off
* the function by assigning the results to the information struct */
unsigned long long shmem = 0, sreclaimable = 0, curmem = 0, curbufmem = 0,
cureasyfree = 0, memavail = 0;
mem_info.memmax = mem_info.memdirty = mem_info.swap = mem_info.swapfree = mem_info.swapmax =
mem_info.memwithbuffers = mem_info.buffers = mem_info.cached = mem_info.memfree =
mem_info.memeasyfree = 0;
if (!(meminfo_fp = open_file("/proc/meminfo", &reported))) { }
while (!feof(meminfo_fp)) {
if (fgets(buf, 255, meminfo_fp) == nullptr) { break; }
if (strncmp(buf, "MemTotal:", 9) == 0) {
sscanf(buf, "%*s %llu", &mem_info.memmax);
} else if (strncmp(buf, "MemFree:", 8) == 0) {
sscanf(buf, "%*s %llu", &mem_info.memfree);
} else if (strncmp(buf, "SwapTotal:", 10) == 0) {
sscanf(buf, "%*s %llu", &mem_info.swapmax);
} else if (strncmp(buf, "SwapFree:", 9) == 0) {
sscanf(buf, "%*s %llu", &mem_info.swapfree);
} else if (strncmp(buf, "Buffers:", 8) == 0) {
sscanf(buf, "%*s %llu", &mem_info.buffers);
} else if (strncmp(buf, "Cached:", 7) == 0) {
sscanf(buf, "%*s %llu", &mem_info.cached);
} else if (strncmp(buf, "Dirty:", 6) == 0) {
sscanf(buf, "%*s %llu", &mem_info.memdirty);
} else if (strncmp(buf, "MemAvailable:", 13) == 0) {
sscanf(buf, "%*s %llu", &memavail);
} else if (strncmp(buf, "Shmem:", 6) == 0) {
sscanf(buf, "%*s %llu", &shmem);
} else if (strncmp(buf, "SReclaimable:", 13) == 0) {
sscanf(buf, "%*s %llu", &sreclaimable);
}
}
curmem = mem_info.memwithbuffers = mem_info.memmax - mem_info.memfree;
cureasyfree = mem_info.memfree;
mem_info.swap = mem_info.swapmax - mem_info.swapfree;
/* Reclaimable memory: does not include shared memory, which is part of cached
but unreclaimable. Includes the reclaimable part of the Slab cache though.
Note: when shared memory is swapped out, shmem decreases and swapfree
decreases - we want this.
*/
curbufmem = (mem_info.cached - shmem) + mem_info.buffers + sreclaimable;
curmem = mem_info.memmax - memavail;
cureasyfree += curbufmem;
/* Now that we know that every calculation is finished we can wrap up
* by assigning the values to the information structure */
mem_info.mem = curmem;
mem_info.bufmem = curbufmem;
mem_info.memeasyfree = cureasyfree;
memused = (float(mem_info.memmax) - float(mem_info.memeasyfree)) / (1024 * 1024);
memmax = float(mem_info.memmax) / (1024 * 1024);
fclose(meminfo_fp);
}
4、运行程序
$ ./cpumem_monitor #执行结果如下:
本文暂时没有评论,来添加一个吧(●'◡'●)