IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++读取Linux设备运行状态信息(一) 读取CPU的占用率 -> 正文阅读

[C++知识库]C++读取Linux设备运行状态信息(一) 读取CPU的占用率

1. /proc文件系统

/proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。它以文件系统的方式为内核与进程提供通信的接口。用户和应用程序可以通过**/proc得到系统的信息,并可以改变内核的某些参数。由于系统的信息,如进程,是动态改变的,所以用户或应用程序读取/proc**目录中的文件时,proc文件系统是动态从系统内核读出所需信息并提交的。

/proc目录中有一些以数字命名的目录,它们是进程目录。系统中当前运行的每一个进程在/proc下都对应一个以进程号为目录名的目录/proc/pid,它们是读取进程信息的接口。此外,在Linux2.6.0-test6以上的版本中/proc/pid目录中有一个task目录,/proc/pid/task目录中也有一些以该进程所拥有的线程的线程号命名的目录/proc/pid/task/tid,它们是读取线程信息的接口。

此外在该文件夹下,还存放中这一些系统运行状态信息的文件。

  • /proc/cpuinfo: 该文件中存放了有关 cpu的相关信息(型号,缓存大小等)。
  • /proc/stat: 该文件中存放cpu运行时间等信息。
  • /proc/loadavg:改文件存放cpu负载率的相关信息。
  • /proc/meminfo:该文件中存放有关运行没存的相关信息。
  • /proc/net/dev: 该文件存中存放有关网络相关的信息。

2. cpu的占用率

cpu的占用率可以从**/proc/stat**文件中读取进行计算。

使用cat查看/proc/stat文件如下:

[root@dtvl3000 /proc]#cat /proc/stat
cpu  3678388 0 15074581 46154810 4397 625 257495 0 0 0
cpu0 3677615 0 15073545 46144781 4204 625 257495 0 0 0
intr 2964323964 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2177975161 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 35760343 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 13 9549734 67311 0 0 0 0 0 0 0 698995824 5124 0 4646 42521 0 0 0 0 0 0 0 0 58 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4827 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 0 70772 9111527 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 11801 0 0 0 0 0 0 31117389 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1526497 0
ctxt 6220711663
btime 1626658532
processes 2274813
procs_running 1
procs_blocked 0
softirq 151260343 63 37309294 141665 64309221 63 63 36288928 3472 209567 12998007

上述第一行,表示cpu总的信息。cpu0表示第一个核的信息,以次类推。计算cpu的占用率,一般用cpu的总信息,即第一行。

有以上信息可以得出 cpu是单核的,cpu这项对应信息如下
cpu     user    nice    system  idle    iowait  irq softirq steal   guest   guest_nice
user:用户态的CPU时间
nice:低优先级程序所占用的用户态的cpu时间
system:处于核心态的运行时间
idle:CPU空闲的时间(不包含IO等待)
iowait:等待IO响应的时间
irq:处理硬件中断的时间
softirq:处理软中断的时间
steal:其他系统所花的时间
guest:运行时间为客户操作系统下的虚拟CPU控制
guest_nice:低优先级程序所占用的用户态的cpu时间
注意:以上所说的时间是指从开机后到现在的总时间(即从CPU加电到当前的累计值)。

因为/proc/stat中的数值都是从系统启动开始累计到当前时刻的积累值,所以需要在不同时间点t1和t2取值进行比较运算,当两个时间点的间隔较短时,就可以把这个计算结果看作是CPU的即时利用率。

CPU的即时利用率的计算公式:

  • CPU在t1到t2时间段总的使用时间 = ( user2+ nice2+ system2+ idle2+ iowait2+ irq2+ softirq2) - ( user1+ nice1+ system1+ idle1+ iowait1+ irq1+ softirq1)

  • CPU在t1到t2时间段空闲使用时间 = (idle2 - idle1)

  • CPU在t1到t2时间段即时利用率 = 1 - CPU空闲使用时间 / CPU总的使用时间

3. C++代码的实现

#include <cstring>
#include <iostream>
#include <stdio.h>
#include <unistd.h>

// 定义一个cpu occupy的结构体,用来存放CPU的信息
typedef struct CPUPACKED
{
    char name[20];       //定义一个char类型的数组名name有20个元素
    unsigned int user;   //定义一个无符号的int类型的user
    unsigned int nice;   //定义一个无符号的int类型的nice
    unsigned int system; //定义一个无符号的int类型的system
    unsigned int idle;   //定义一个无符号的int类型的idle
    unsigned int lowait;
    unsigned int irq;
    unsigned int softirq;
} CPU_OCCUPY;

// 该函数,利用上述公式。计算出两段时间的之间的CPU占用率
// 输入为:当前时刻和上一采样时刻cpu的信息
double getCpuUse(CPU_OCCUPY *o, CPU_OCCUPY *n)
{
    std::cout << "test" << std::endl; 
    unsigned long od, nd;
    od = (unsigned long)(o->user + o->nice + o->system + o->idle + o->lowait + o->irq + o->softirq); //第一次(用户+优先级+系统+空闲)的时间再赋给od
    nd = (unsigned long)(n->user + n->nice + n->system + n->idle + n->lowait + n->irq + n->softirq); //第二次(用户+优先级+系统+空闲)的时间再赋给od
    double sum = nd - od;
    double idle = n->idle - o->idle;
    return (sum - idle) / sum;
}
int main()
{
    CPU_OCCUPY old_cpu_occupy;
    while (true)
    {
        FILE *fd;       // 定义打开文件的指针
        char buff[256]; // 定义个数组,用来存放从文件中读取CPU的信息
        CPU_OCCUPY cpu_occupy;
        std::string cpu_use = "";

        fd = fopen("/proc/stat", "r");

        if (fd != NULL)
        {
            // 读取第一行的信息,cpu整体信息
            fgets(buff, sizeof(buff), fd);
            if (strstr(buff, "cpu") != NULL) // 返回与"cpu"在buff中的地址,如果没有,返回空指针
            {
                // 从字符串格式化输出
                sscanf(buff, "%s %u %u %u %u %u %u %u", cpu_occupy.name, &cpu_occupy.user, &cpu_occupy.nice, &cpu_occupy.system, &cpu_occupy.idle, &cpu_occupy.lowait, &cpu_occupy.irq, &cpu_occupy.softirq);
                // cpu的占用率 = (当前时刻的任务占用cpu总时间-前一时刻的任务占用cpu总时间)/ (当前时刻 - 前一时刻的总时间)
                cpu_use = std::to_string(getCpuUse(&old_cpu_occupy, &cpu_occupy) * 100) + "%";
                old_cpu_occupy = cpu_occupy;
            }
        }
        std::cout << cpu_use << std::endl; // 打印cpu的占用率
        sleep(1);                          // 延时1s;
    }
}

实测与实际情况差不多。
运行结果:
第一次查询显示100%的原因是,刚开始运行程序,没有初始值。
请添加图片描述

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-28 07:31:54  更:2021-07-28 07:34:25 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年4日历 -2024/4/29 11:05:23-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码