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]
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>
typedef struct CPUPACKED
{
char name[20];
unsigned int user;
unsigned int nice;
unsigned int system;
unsigned int idle;
unsigned int lowait;
unsigned int irq;
unsigned int softirq;
} CPU_OCCUPY;
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);
nd = (unsigned long)(n->user + n->nice + n->system + n->idle + n->lowait + n->irq + n->softirq);
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_OCCUPY cpu_occupy;
std::string cpu_use = "";
fd = fopen("/proc/stat", "r");
if (fd != NULL)
{
fgets(buff, sizeof(buff), fd);
if (strstr(buff, "cpu") != NULL)
{
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_use = std::to_string(getCpuUse(&old_cpu_occupy, &cpu_occupy) * 100) + "%";
old_cpu_occupy = cpu_occupy;
}
}
std::cout << cpu_use << std::endl;
sleep(1);
}
}
实测与实际情况差不多。 运行结果: 第一次查询显示100%的原因是,刚开始运行程序,没有初始值。
|