c/c++实现linux下各个CPU统计信息获取

目录

一、实现原理

二、代码实现

三、编译


一、实现原理

        在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]$
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

py_free-物联智能

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值