TX2 ubuntu CPU占用率、占用物理内存、占用虚拟内存、进程ID、系统温度

文件解释

在实际工作中有时需要程序打印出某个进程的内存占用情况以作参考, 下面介绍一种通过Linux下的伪文件系统/proc计算某进程内存占用的程序实现方法.

首先, 为什么会有所谓的 伪文件 呢. Linux系统的文件类型大致可分为三类: 普通文件, 目录文件和伪文件. 伪文件不是用来存储数据的, 因此这些文件不占用磁盘空间, 只是存在于内存中. /proc让你可以与内核内部数据进行交互, 获取有关进程的有用信息.

下面主要介绍一下 /proc下面的四个文件:
/proc/stat, /proc/meminfo, /proc/<pid>/stat, /proc/<pid>/status.
以及/sys/devices/virtual/thermal/thermal_zone*/下的文件

/proc/stat存放系统的cpu时间, 该文件包含了所有cpu活动的信息.

cpu  72389 2891 16811 1148664 31374 0 67 0 0 0
cpu0 17608 452 3786 288899 6210 0 30 0 0 0
cpu1 18724 926 4598 285844 8911 0 15 0 0 0
cpu2 16803 658 3726 288710 7220 0 7 0 0 0
cpu3 19254 855 4700 285209 9032 0 13 0 0 0
...
...
...

/proc/meminfo存放系统的内存信息, 通过文件中各个变量的名字便可知其代表的信息.

MemTotal:        4046236 kB
MemFree:         1054440 kB
MemAvailable:    2460060 kB
Buffers:          359688 kB
Cached:          1158056 kB
SwapCached:            0 kB
Active:          2020096 kB
Inactive:         677948 kB
Active(anon):    1181376 kB

...
...
...

/proc/<pid>/stat存放某个进程的cpu信息

2476 (firefox) S 1773 1910 1910 0 -1 4210688 3413511 1712 757 1 45466 4629 2 7 20 0 57 0 20381 1774743552 150565 18446744073709551615 94844693012480 94844693126372 140732961864784 140732961858304 139747170914269 0 0 4096 33572079 0 0 0 17 2 0 0 1178 0 0 94844695226592 94844695228536 94844713955328 140732961867643 140732961867668 140732961867668 140732961869791 0

/proc/<pid>/status存放某个进程的cpu信息以及一些综合信息

Name:	firefox
State:	S (sleeping)
Tgid:	2476
Ngid:	0
Pid:	2476
PPid:	1773
TracerPid:	0
Uid:	1000	1000	1000	1000
Gid:	1000	1000	1000	1000
FDSize:	256
Groups:	4 24 27 30 46 108 124 1000 
NStgid:	2476
NSpid:	2476
NSpgid:	1910
NSsid:	1910
VmPeak:	 1722812 kB
VmSize:	 1690920 kB
VmLck:	       0 kB
VmPin:	       0 kB
VmHWM:	  684048 kB
VmRSS:	  600324 kB
VmData:	  993040 kB
VmStk:	     192 kB
...
...
...

以上数据都可以通过文件读取的方式来获取. 根据自己实验的需要可以计算相应的数据, 比如pmem = VmRSS/MemTotal*100等等.

/sys/devices/virtual/thermal/thermal_zone*/type文件:记录的是温度类型, 查看硬件
在这里插入图片描述
/sys/devices/virtual/thermal/thermal_zone*/temp查看温度,以下数字分别对应以上硬件,将数字除以1000得出实际温度(摄氏度)
在这里插入图片描述

C/C++代码获取

get_status.h

//
// Created by adu on 6/14/20.
//

#ifndef MAVKIT_MAVHX_TX2_GET_STATUS_H
#define MAVKIT_MAVHX_TX2_GET_STATUS_H

#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <string.h>
#include <stdlib.h>
#include <string>
#include <thread>
#include <mavhx/mavhx_msg_tx2_status.h>
#include <mavkit/MavlinkLogWriter.h>

#define VMRSS_LINE 17   // 随着不同系统改变,应用之前查看文件确认行数
#define VMSIZE_LINE 13  // 随着不同系统改变,应用之前查看文件确认行数
#define PROCESS_ITEM 14

typedef struct {
    unsigned long user;
    unsigned long nice;
    unsigned long system;
    unsigned long idle;
}Total_Cpu_Occupy_t;

typedef struct {
    unsigned int pid;
    unsigned long utime;  //user time
    unsigned long stime;  //kernel time
    unsigned long cutime; //all user time
    unsigned long cstime; //all dead time
}Proc_Cpu_Occupy_t;

class MavlinkLogWriter;

class Tx2GetStatus{
public:
    Tx2GetStatus();
    ~Tx2GetStatus();

    void start();
    void join();
    void run();

    void SetLogWriter(MavlinkLogWriter * pLogWriter);

// 得到用户名称
    void GetUserName(std::string userName);
//得到进程名字
    void GetProcessName(std::string processName);
//获取第N项开始的指针
    const char* get_items(const char*buffer ,unsigned int item);
//获取总的CPU时间
    unsigned long get_cpu_total_occupy();
//获取进程的CPU时间
    unsigned long get_cpu_proc_occupy(unsigned int pid);
//获取CPU占用率
    float get_proc_cpu(unsigned int pid);
//获取进程占用内存
    unsigned int get_proc_mem(unsigned int pid);
//获取进程占用虚拟内存
    unsigned int get_proc_virtualmem(unsigned int pid);
//进程本身
    int get_pid(const char* process_name, const char* user = nullptr);
// 获得CPU温度
    int get_cpu_temp();

private:
    std::string msProcessName;
    std::string msUserName;
    MavlinkLogWriter* mpLogWriter;
    std::thread *starting_thread;
};

#endif //MAVKIT_MAVHX_TX2_GET_STATUS_H

get_status.cpp

//
// Created by adu on 6/14/20.
//
#include <mavhx/mavhx_tx2_get_status.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <string.h>
#include <stdlib.h>
#include <string>
#include <iostream>

#define VMRSS_LINE 17
#define VMSIZE_LINE 13
#define PROCESS_ITEM 14

Tx2GetStatus::Tx2GetStatus() : mpLogWriter(NULL), starting_thread(NULL) {}

Tx2GetStatus::~Tx2GetStatus() {}

void Tx2GetStatus::start() {
    if(starting_thread == NULL) {
        starting_thread = new std::thread(&Tx2GetStatus::run, this);
    }
}

void Tx2GetStatus::join() {
    starting_thread->join();
}

void Tx2GetStatus::run() {
    mavlink_message_r SMsgTx2Status;
    mavlink_tx2_status_t STx2Status;
    if(msProcessName.empty()){
        throw std::logic_error("Process Name is NULL.");
    }
    int32_t pid = get_pid(msProcessName.c_str(), msUserName.c_str());
    std::cout << "process id  " << pid << std::endl;
    STx2Status.pid = pid;
    while (true) {
        STx2Status.temp = get_cpu_temp();
        STx2Status.pcpu = get_proc_cpu(pid);
        STx2Status.pmem = get_proc_mem(pid);
        STx2Status.vmem = get_proc_virtualmem(pid);
        mavlink_msg_tx2_status_encode(&SMsgTx2Status, &STx2Status);
        if( mpLogWriter != NULL) {
            mpLogWriter->send_message(SMsgTx2Status);
        }
        sleep(2);
    }
}

void Tx2GetStatus::SetLogWriter(MavlinkLogWriter * pLogWriter){
    mpLogWriter = pLogWriter;
}

void Tx2GetStatus::GetUserName(std::string userName){
    msUserName = userName;
}
//得到进程名字
void Tx2GetStatus::GetProcessName( std::string processName) {
    msProcessName = processName;
}
//获取第N项开始的指针
const char* Tx2GetStatus::get_items(const char*buffer ,unsigned int item){

    const char *p =buffer;

    int len = strlen(buffer);
    int count = 0;

    for (int i=0; i<len;i++){
        if (' ' == *p){
            count ++;
            if(count == item -1){
                p++;
                break;
            }
        }
        p++;
    }

    return p;
}
//获取总的CPU时间
unsigned long Tx2GetStatus::get_cpu_total_occupy(){

    FILE *fd;
    char buff[1024]={0};
    Total_Cpu_Occupy_t t;

    fd =fopen("/proc/stat","r");
    if (nullptr == fd){
        return 0;
    }

    fgets(buff,sizeof(buff),fd);
    char name[64]={0};
    sscanf(buff,"%s %ld %ld %ld %ld",name,&t.user,&t.nice,&t.system,&t.idle);
    fclose(fd);

    return (t.user + t.nice + t.system + t.idle);
}
//获取进程的CPU时间
unsigned long Tx2GetStatus::get_cpu_proc_occupy(unsigned int pid){

    char file_name[64]={0};
    Proc_Cpu_Occupy_t t;
    FILE *fd;
    char line_buff[1024]={0};
    sprintf(file_name,"/proc/%d/stat",pid);

    fd = fopen(file_name,"r");
    if(nullptr == fd){
        return 0;
    }

    fgets(line_buff,sizeof(line_buff),fd);

    sscanf(line_buff,"%u",&t.pid);
    const char *q =get_items(line_buff,PROCESS_ITEM);
    sscanf(q,"%ld %ld %ld %ld",&t.utime,&t.stime,&t.cutime,&t.cstime);
    fclose(fd);

    return (t.utime + t.stime + t.cutime + t.cstime);
}
//获取CPU占用率
float Tx2GetStatus::get_proc_cpu(unsigned int pid){

    unsigned long totalcputime1,totalcputime2;
    unsigned long procputime1,procputime2;

    totalcputime1=get_cpu_total_occupy();
    procputime1=get_cpu_proc_occupy(pid);

    usleep(500000);

    totalcputime2=get_cpu_total_occupy();
    procputime2=get_cpu_proc_occupy(pid);

    float pcpu = 0.0;
    if(0 != totalcputime2-totalcputime1){
        pcpu=100.0 * (procputime2-procputime1)/(totalcputime2-totalcputime1);
    }

    return pcpu;
}
//获取进程占用内存
unsigned int Tx2GetStatus::get_proc_mem(unsigned int pid){

    char file_name[64]={0};
    FILE *fd;
    char line_buff[512]={0};
    sprintf(file_name,"/proc/%d/status",pid);

    fd =fopen(file_name,"r");
    if(nullptr == fd){
        return 0;
    }

    char name[64];
    int vmrss;
    //获取vmrss:实际物理内存占用
    //读取VmRSS这一行的数据
    for (int i=0; i<VMRSS_LINE-1;i++){
        fgets(line_buff,sizeof(line_buff),fd);
    }

    fgets(line_buff,sizeof(line_buff),fd);
    sscanf(line_buff,"%s %d",name,&vmrss);
    fclose(fd);

    return vmrss;
}
//获取进程占用虚拟内存
unsigned int Tx2GetStatus::get_proc_virtualmem(unsigned int pid){

    char file_name[64]={0};
    FILE *fd;
    char line_buff[512]={0};
    sprintf(file_name,"/proc/%d/status",pid);

    fd =fopen(file_name,"r");
    if(nullptr == fd){
        return 0;
    }

    char name[64];
    int vmsize;
    for (int i=0; i<VMSIZE_LINE-1;i++){
        fgets(line_buff,sizeof(line_buff),fd);
    }

    fgets(line_buff,sizeof(line_buff),fd);
    sscanf(line_buff,"%s %d",name,&vmsize);
    fclose(fd);

    return vmsize;
}
//进程本身
int Tx2GetStatus::get_pid(const char* process_name, const char* user)
{
    if(user == nullptr){
        user = getlogin();
    }

    char cmd[512];
    if (user){
        sprintf(cmd, "pgrep %s -u %s", process_name, user);
    }

    FILE *pstr = popen(cmd,"r");

    if(pstr == nullptr){
        return 0;
    }

    char buff[512];
    ::memset(buff, 0, sizeof(buff));
    if(NULL == fgets(buff, 512, pstr)){
        return 0;
    }

    return atoi(buff);
}
// 获得CPU温度
int Tx2GetStatus::get_cpu_temp()
{
    FILE *fd;
    int temp;
    char buff[256];

    fd = fopen("/sys/devices/virtual/thermal/thermal_zone0/temp","r");
    fgets(buff,sizeof(buff),fd);
    sscanf(buff, "%d", &temp);

    fclose(fd);

    return temp/1000;
}

参考链接:
https://www.cnblogs.com/bozhicheng/p/6216667.html
http://blog.sina.com.cn/s/blog_49efd54001019r1j.html
https://blog.csdn.net/chenjambo/article/details/80945992

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值