目录
一、实现原理
在Linux系统中,操作系统屏蔽了用户直接访问系统内核,提供了LKM机制间接在内核空间工作,在LKM机制中一个重要的组成部分就是proc伪文件系统,它为用户提供了动态操作Linux内核信息的接口。linux各个CPU统计信息通过/proc/stat文件句柄进行访问获取,例如,采用cat命令读取相关信息,如下(本文在win10-VMware下安装的centos7虚拟机测试命令):
[py@pyfree cpu_info_test]$ cat /proc/stat |grep cpu
cpu 1161 13 1548 774440 4158 0 45 0 0 0
cpu0 520 8 829 387570 1950 0 26 0 0 0
cpu1 641 4 718 386869 2208 0 18 0 0 0
[py@pyfree cpu_info_test]$
另外借助awk命令, 可以通过 print、printf 将数据输出到标准输出或重定向到文件
[py@pyfree cpu_info_test]$ /bin/cat /proc/stat |grep cpu|awk '{print($2,$3,$4,$5,$6,$7,$8)}'
1175 13 1581 843029 4162 0 46
526 8 848 421885 1950 0 27
648 4 733 421144 2212 0 19
[pyg@pyfree cpu_info_test]$
c/c++读取CPU信息,就是打开“cat /proc/stat”命令管道文件句柄,识别该文件内容格式,从中读取到需要的数据信息。
二、代码实现
工程设计:
CPU_info_test
bin
src
cpu.h
cpu.cpp
main.cpp
Makefile
cpu.h,定义cpu统计信息结构体,通过popen打开“cat /proc/stat”命令管道文件句柄获取统计信息
#ifndef _CPU_INFO_H_
#define _CPU_INFO_H_
/**********************************************************************************
*Copyright 2020-09-28, pyfree
*
*File Name : epoll_socket.h
*File Mark :
*Summary :
*
*Current Version : 1.00
*Author : pyfree
*FinishDate :
*
*Replace Version :
*Author :
*FinishDate :
***********************************************************************************/
#include <inttypes.h>
#include <vector>
typedef struct {
uint64_t user;
uint64_t nice;
uint64_t sys;
uint64_t idle;
uint64_t iowait;
uint64_t irq;
uint64_t softIrq;
uint64_t total;
}CpuInfo;
typedef struct {
std::vector<CpuInfo> cup_infos;
}CpuStatus;
// 从 /proc/stat 中获取cpu 采样数据
int GetCpuStatus(CpuStatus *pcpu);
#endif //_CPU_INFO_H_
cpu.cpp
#include "cpu.h"
#include <stdio.h>
//调用linux系统命令获取cpu信息
#define CMD "/bin/cat /proc/stat |grep cpu|awk \'{print $2\" \"$3\" \"$4\" \"$5\" \"$6\" \"$7\" \"$8}\'"
int GetCpuStatus(CpuStatus *pcpu)
{
FILE *fp = popen(CMD, "r");
if(fp == NULL) {
return -2;
}
CpuInfo plast = {0};
while( fscanf(fp, "%" PRIu64" %" PRIu64" %" PRIu64" %" PRIu64" %" PRIu64" %" PRIu64" %" PRIu64,
&plast.user, &plast.nice, &plast.sys, &plast.idle,
&plast.iowait, &plast.irq, &plast.softIrq) == 7)
{
plast.total = plast.user + plast.nice + plast.sys
+ plast.idle + plast.iowait + plast.irq + plast.softIrq;
pcpu->cup_infos.push_back(plast);
}
pclose(fp);
return pcpu->cup_infos.size();
}
main.cpp
#include "cpu.h"
#include <stdio.h>
int main(int argc, char* argv[])
{
CpuStatus tcs;
GetCpuStatus(&tcs);
for(int i=0; i<tcs.cup_infos.size(); i++)
{
printf("read cup: \ntotal:%" PRIu64" \nuser:%" PRIu64" \nnice:%" PRIu64" \nsys:%" PRIu64
"\nidle:%" PRIu64" \niowait:%" PRIu64" \nirq:%" PRIu64" \nsoftIrq:%" PRIu64 "\n",
tcs.cup_infos.at(i).total, tcs.cup_infos.at(i).user, tcs.cup_infos.at(i).nice, tcs.cup_infos.at(i).sys,
tcs.cup_infos.at(i).idle, tcs.cup_infos.at(i).iowait, tcs.cup_infos.at(i).irq, tcs.cup_infos.at(i).softIrq);
}
return 0;
}
三、编译
Makefile
#/bin/sh
CX= g++
BIN := ./bin
TARGET := cpu_test.bin
FLAGS := -std=c++11
#-static
SRCDIR := ./src
#INCLUDES
INCLUDEDIR := -I"$(SRCDIR)"
source := $(wildcard $(SRCDIR)/*.cpp)
$(TARGET) :
$(CX) $(FLAGS) $(INCLUDEDIR) $(source) -o $(BIN)/$(TARGET)
clean:
rm $(BIN)/$(TARGET)
编译及输出结果(cd cpu_info_test && make && ./bin/cup_test.bin):
[py@pyfree cpu_info_test]$ make
g++ -std=c++11 -I"./src" ./src/cpu.cpp ./src/main.cpp -o ./bin/cpu_test.bin
[py@pyfree cpu_info_test]$ ./bin/cpu_test.bin
read cup:
total:929032
user:1208
nice:13
sys:1627
idle:921975
iowait:4163
irq:0
softIrq:46
read cup:
total:464777
user:538
nice:8
sys:872
idle:461382
iowait:1950
irq:0
softIrq:27
read cup:
total:464253
user:670
nice:4
sys:755
idle:460592
iowait:2213
irq:0
softIrq:19
[py@pyfree cpu_info_test]$