标签:20 0.0 top jackie 内存 str Linux CPU
Linux top 工具中各字段的含义:
top输出信息:
jackie@jackie-lenovo:~$ top
top - 09:19:00 up 2 days, 14:46, 5 users, load average: 0.46, 0.57, 0.48
Tasks: 621 total, 1 running, 537 sleeping, 0 stopped, 0 zombie
%Cpu(s): 4.5 us, 0.8 sy, 0.0 ni, 94.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 16334368 total, 6160820 free, 2904640 used, 7268908 buff/cache
KiB Swap: 31249404 total, 30721732 free, 527672 used. 12812168 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
4030 root 20 0 428892 59252 27560 S 45.5 0.4 7:30.01 sunloginclient
14838 root 20 0 484592 80636 44664 S 8.0 0.5 128:57.32 Xorg
934 root 20 0 1162808 6916 4408 S 3.3 0.0 74:52.88 sunloginclient
14865 root -51 0 0 0 0 S 2.7 0.0 36:43.09 irq/132-nvidia
22985 jackie 20 0 1057640 41444 27464 S 2.3 0.3 63:40.92 sunloginclient
4732 jackie 20 0 36.441g 146728 58072 S 1.0 0.9 7:24.02 code
4472 jackie 20 0 681180 144304 74592 S 0.7 0.9 7:29.98 code
7820 jackie 20 0 20392 4404 3060 S 0.7 0.0 16:49.75 htop
339 jackie 20 0 968128 93868 33804 S 0.3 0.6 0:10.31 node
930 root 20 0 125636 40 40 S 0.3 0.0 8:26.13 oray_rundaemon
1195 root 20 0 1218680 5676 864 S 0.3 0.0 8:27.24 containerd
3839 jackie 20 0 1076996 202932 35944 S 0.3 1.2 0:20.31 node
7628 jackie 20 0 775140 57340 35084 S 0.3 0.4 1:26.83 /usr/bin/x-term
7862 jackie 20 0 35848 4152 3076 R 0.3 0.0 0:00.03 top
8093 jackie 20 0 32.762g 195008 118932 S 0.3 1.2 1:10.97 chrome
22808 jackie 20 0 1732096 157504 56712 S 0.3 1.0 7:45.26 compiz
1 root 20 0 185268 5284 3696 S 0.0 0.0 0:02.73 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.05 kthreadd
4 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 kworker/0:0H
6 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 mm_percpu_wq
...
第1行解释:
top - 09:19:00 up 2 days, 14:46, 5 users, load average: 0.46, 0.57, 0.48
字段 |
含义 |
09:19:00 |
系统当前时间 |
up 2 days, 14:46 |
系统运行时间。本机已运行2天14小时46分钟 |
5 users |
当前登录了5个用户 |
load average: 0.46, 0.57, 0.48 |
系统在之前 1 分钟、5 分钟、15 分钟的平均负载。如果 CPU 是单核的,则这个数值超过 1 就是高负载;如果 CPU 是四核的,则这个数值超过 4 就是高负载 ;(这个平均负载完全是依据个人经验来进行判断的,一般认为不应该超过服务器 CPU 的核数) |
第2行解释:
Tasks: 621 total, 1 running, 537 sleeping, 0 stopped, 0 zombie
字段 |
含义 |
621 total |
系统中的进程总数 |
1 running |
正在运行的进程数 |
537 sleeping |
睡眠的进程数 |
0 stopped |
停止的进程数 |
0 zombie |
僵尸进程数。如果不是 0,则需要手工检查僵尸进程 |
第3行解释:
%Cpu(s): 4.5 us, 0.8 sy, 0.0 ni, 94.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
字段 |
含义 |
4.5 us, |
用户模式占用的 CPU 百分比。表示的是所有用户进程占用整个cpu的平均值,由于每个核心占用的百分比不同,所以按平均值来算比较有参考意义。参考 |
0.8 sy, |
系统模式占用的 CPU 百分比 |
0.0 ni, |
改变过优先级的用户进程占用的 CPU 百分比 |
94.7 id, |
空闲 CPU 占用的 CPU 百分比 |
0.0 wa, |
等待输入/输出的进程占用的 CPU 百分比 |
0.0 hi, |
硬中断请求服务占用的 CPU 百分比 |
0.0 si, |
软中断请求服务占用的 CPU 百分比 |
0.0 st |
st(steal time)意为虚拟时间百分比,就是当有虚拟机时,虚拟 CPU 等待实际 CPU 的时间百分比 |
第4行解释:
KiB Mem : 16334368 total, 6160820 free, 2904640 used, 7268908 buff/cache
字段 |
含义 |
16334368 total, |
物理内存的总量,单位为KB |
6160820 free, |
空闲的物理内存数量 |
2904640 used, |
己经使用的物理内存数量 |
7268908 buff/cache |
作为缓冲/缓存的内存数量。 简单来说,缓存(cache)是用来加速数据从硬盘中"读取"的,而缓冲(buffer)是用来加速数据"写入"硬盘的。 |
第5行解释:
KiB Swap: 31249404 total, 30721732 free, 527672 used. 12812168 avail Mem
字段 |
含义 |
KiB Swap: 31249404 total, |
交换分区(虚拟内存)的总大小 |
30721732 free, |
空闲交换分区的大小 |
527672 used. |
已经使用的交换分区的大小 |
12812168 avail Mem |
作为缓存的交换分区的大小 |
第6行解释:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
字段 |
含义 |
PID |
进程的 ID |
USER |
该进程所属的用户。 |
PR |
优先级,数值越小优先级越高。 |
NI |
Nice值的范围从-20到+19(不同系统的值范围是不一样的),正值表示低优先级,负值表示高优先级,值为零则表示不会调整该进程的优先级。 |
VIRT |
进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES |
RES |
进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA |
SHR |
共享内存大小,单位kb |
S |
进程状态。D=不可中断的睡眠状态 R=运行 S=睡眠 T=跟踪/停止 Z=僵尸进程 |
%CPU |
上次更新到现在的CPU时间占用百分比。%CPU显示的是进程占用一个核的百分比,而不是整个cpu(所有核心)的百分比,有时候可能大于100,那是因为该进程启用了多线程占用了多个核心,所以有时候我们看该值得时候会超过100%,但不会超过总核数*100。 |
%MEM |
进程使用的物理内存百分比 ,“RES” is the memory consumed by the process in RAM, and “%MEM” expresses this value as a percentage of the total RAM available. 参考 |
TIME+ |
该进程共占用的 CPU 时间。TIME+是指的进程所使用的CPU时间,不是进程启动到现在的时间,因此,如果一个进程使用的cpu很少,那即使这个进程已经存在N长时间,TIME+也是很小的数值。此外,如果你的系统有多个CPU,或者是多核CPU的话,那么,进程占用多个cpu的时间是累加的。例如:2:32.45表示该进程共占用了2分钟 + 30秒 + 十分之4秒 + 百分之5秒的时间。 参考 |
COMMAND |
进程名称(命令名/命令行) |
参考资料:
-
Linux top命令详解:持续监听进程运行状态
-
Linux top命令的用法详细详解
-
A Guide to the Linux “Top” Command
-
Linux top命令里面%CPU和cpu(s)的差别
-
[linux top 中的time+]
-
top这个命令在统计存在多线程和共享内存的进程的资源时,确实存在缺陷
LInux top常见命令展示
默认命令:top
jackie@jackie-lenovo:~$ top
top - 15:08:10 up 4 days, 20:35, 4 users, load average: 0.85, 0.86, 1.23
Tasks: 370 total, 1 running, 275 sleeping, 8 stopped, 3 zombie
%Cpu(s): 3.7 us, 0.7 sy, 0.0 ni, 95.4 id, 0.1 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 16334368 total, 5885400 free, 3787396 used, 6661572 buff/cache
KiB Swap: 31249404 total, 30699972 free, 549432 used. 11897564 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
17406 root 20 0 494428 57260 27452 S 50.0 0.4 154:33.15 sunloginclient
14838 root 20 0 524608 112368 44232 S 12.5 0.7 291:02.84 Xorg
9660 jackie 20 0 35584 3932 3120 R 6.2 0.0 0:00.01 top
1 root 20 0 186308 6292 3676 S 0.0 0.0 0:08.28 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.08 kthreadd
4 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 kworker/0:0H
6 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 mm_percpu_wq
...
以上区域重复刷新
Bath-mode 命令:top -b
有利于后期的文本处理
top - 15:17:15 up 4 days, 20:44, 4 users, load average: 0.62, 0.78, 1.01
Tasks: 371 total, 2 running, 275 sleeping, 8 stopped, 3 zombie
%Cpu(s): 3.7 us, 0.7 sy, 0.0 ni, 95.4 id, 0.1 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 16334368 total, 5848800 free, 3790312 used, 6695256 buff/cache
KiB Swap: 31249404 total, 30700228 free, 549176 used. 11894536 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
17406 root 20 0 494428 56784 27452 S 37.5 0.3 158:43.97 sunloginclient
9849 jackie 20 0 35436 3804 3260 R 6.2 0.0 0:00.02 top
...
29531 jackie 20 0 354712 4060 3536 S 0.0 0.0 0:00.03 gvfsd-network
29581 jackie 20 0 363452 1116 1016 S 0.0 0.0 0:00.38 gvfsd-dnssd
top - 15:17:18 up 4 days, 20:44, 4 users, load average: 0.57, 0.77, 1.01
Tasks: 371 total, 2 running, 275 sleeping, 8 stopped, 3 zombie
%Cpu(s): 4.6 us, 0.8 sy, 0.0 ni, 94.6 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 16334368 total, 5848360 free, 3790808 used, 6695200 buff/cache
KiB Swap: 31249404 total, 30700228 free, 549176 used. 11894096 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
17406 root 20 0 494428 56784 27452 S 46.4 0.3 158:45.38 sunloginclient
14838 root 20 0 524608 112368 44232 S 7.2 0.7 291:44.30 Xorg
...
29531 jackie 20 0 354712 4060 3536 S 0.0 0.0 0:00.03 gvfsd-network
29581 jackie 20 0 363452 1116 1016 S 0.0 0.0 0:00.38 gvfsd-dnssd
...
新文本会不断追加,而非在固定区域内重复刷新,这有利于将其保存到文件中做进一步数据处理
正则表达式:top -b | grep -E "top"
筛选出含某个字符串的行
jackie@jackie-lenovo:~$ top -b | grep -E "top"
top - 15:26:25 up 4 days, 20:53, 4 users, load average: 0.94, 0.78, 0.91
Tasks: 372 total, 1 running, 277 sleeping, 8 stopped, 3 zombie
9948 jackie 20 0 35436 3736 3192 R 6.2 0.0 0:00.01 top
5597 jackie 20 0 34564 3284 2976 T 0.0 0.0 0:00.00 top
5611 jackie 20 0 34564 3264 2960 T 0.0 0.0 0:00.00 top
9666 jackie 20 0 35560 4040 3196 S 0.0 0.0 0:03.43 top
13477 jackie 20 0 34564 3332 3020 T 0.0 0.0 0:00.00 top
14659 jackie 20 0 20248 4432 2964 S 0.0 0.0 14:31.35 htop
top - 15:26:28 up 4 days, 20:53, 4 users, load average: 0.94, 0.78, 0.91
Tasks: 372 total, 1 running, 277 sleeping, 8 stopped, 3 zombie
14659 jackie 20 0 20248 4432 2964 S 1.0 0.0 14:31.38 htop
9666 jackie 20 0 35560 4040 3196 S 0.3 0.0 0:03.44 top
9948 jackie 20 0 35436 3736 3192 R 0.3 0.0 0:00.02 top
5597 jackie 20 0 34564 3284 2976 T 0.0 0.0 0:00.00 top
5611 jackie 20 0 34564 3264 2960 T 0.0 0.0 0:00.00 top
13477 jackie 20 0 34564 3332 3020 T 0.0 0.0 0:00.00 top
...
正则表达式:top -b | grep -E "\<top\>"
精确筛含特定单词的行
jackie@jackie-lenovo:~$ top -b | grep -E "\<top\>"
top - 15:32:56 up 4 days, 21:00, 4 users, load average: 1.07, 0.80, 0.86
10884 jackie 20 0 35436 3660 3120 R 11.8 0.0 0:00.02 top
5597 jackie 20 0 34564 3284 2976 T 0.0 0.0 0:00.00 top
5611 jackie 20 0 34564 3264 2960 T 0.0 0.0 0:00.00 top
13477 jackie 20 0 34564 3332 3020 T 0.0 0.0 0:00.00 top
正则表达式:top -b | grep -E "jackie.*?top"
筛同时含串1和串2的行
jackie@jackie-lenovo:~$ top -b | grep -E "jackie.*?top"
5597 jackie 20 0 34564 3284 2976 T 0.0 0.0 0:00.00 top
5611 jackie 20 0 34564 3264 2960 T 0.0 0.0 0:00.00 top
13477 jackie 20 0 34564 3332 3020 T 0.0 0.0 0:00.00 top
13525 jackie 20 0 35436 3724 3172 R 0.0 0.0 0:00.00 top
14659 jackie 20 0 20248 4432 2964 S 0.0 0.0 14:43.92 htop
其中,【.*?】表示任意多个任意字符
正则表达式:top -b | grep -E "top|front"
筛含字符串1或字符串2的行
jackie@jackie-lenovo:~$ top -b | grep -E "top|front"
top - 15:36:19 up 4 days, 21:03, 4 users, load average: 1.55, 1.11, 0.97
Tasks: 377 total, 2 running, 282 sleeping, 8 stopped, 3 zombie
11936 jackie 20 0 35436 3804 3260 R 6.2 0.0 0:00.01 top
5597 jackie 20 0 34564 3284 2976 T 0.0 0.0 0:00.00 top
5611 jackie 20 0 34564 3264 2960 T 0.0 0.0 0:00.00 top
10057 jackie 20 0 790928 239680 33956 S 0.0 1.5 1:01.70 front_end_node
13477 jackie 20 0 34564 3332 3020 T 0.0 0.0 0:00.00 top
14659 jackie 20 0 20248 4432 2964 S 0.0 0.0 14:40.39 htop
控制更新次数: top -n 3 -b | grep -E "front"
更新三次后停止
jackie@jackie-lenovo:~$ top -n 3 -b | grep -E "front"
10057 jackie 20 0 841572 265916 33956 S 0.0 1.6 3:50.67 front_end_node
10057 jackie 20 0 841744 265976 33956 S 19.9 1.6 3:51.27 front_end_node
10057 jackie 20 0 841744 265976 33956 S 14.3 1.6 3:51.70 front_end_node
控制更新周期:top -d 1 -b | grep -E "front"
1秒更新一次(默认周期3秒)
jackie@jackie-lenovo:~$ top -d 1 -b | grep -E "front"
10057 jackie 20 0 863648 278540 33956 S 93.8 1.7 4:05.10 front_end_node
10057 jackie 20 0 863648 278540 33956 S 14.9 1.7 4:05.25 front_end_node
10057 jackie 20 0 863712 278564 33956 R 21.8 1.7 4:05.47 front_end_node
10057 jackie 20 0 863712 278564 33956 S 28.7 1.7 4:05.76 front_end_node
10057 jackie 20 0 931008 317888 33956 R 18.0 1.9 4:05.94 front_end_node
...
利用C++调用top的shell命令然后解析:便于提取和处理数据
代码部分
#include <stdio.h>
#include <cstring>
#include <unistd.h>
#include <iostream>
#include <fstream>
#include <list>
#include <sstream>
#include <chrono>
// http://c.biancheng.net/view/1065.html
// https://www.jb51.net/article/40807.htm
// https://www.jianshu.com/p/3c078505fffa
struct TOP1HeaderInfo
{
// 12:26:46 系统当前时间
int system_time_hh = 0;
int system_time_mm = 0;
int system_time_ss = 0;
// up 1 day, 13:32 系统的运行时间.本机己经运行 1 天 13 小时 32 分钟
int system_runing_time_dd = 0;
int system_runing_time_hh = 0;
int system_runing_time_mm = 0;
// 2 users 当前登录了两个用户
int num_users = 0;
// load average: 0.00,0.00,0.00
// 系统在之前 1 分钟、5 分钟、15 分钟的平均负载。
// 如果 CPU 是单核的,则这个数值超过 1 就是高负载:
// 如果 CPU 是四核的,则这个数值超过 4 就是高负载
//(这个平均负载完全是依据个人经验来进行判断的,一般认为不应该超过服务器 CPU 的核数)
double load_average_1minuts = 0.0;
double load_average_5minuts = 0.0;
double load_average_15minuts = 0.0;
};
struct TOP2TasksInfo
{
// Tasks: 95 total 系统中的进程总数
int total_tasks = 0;
// 1 running 正在运行的进程数
int running_tasks = 0;
// 94 sleeping 睡眠的进程数
int sleeping_tasks = 0;
// 0 stopped 正在停止的进程数
int stopped_tasks = 0;
// 0 zombie 僵尸进程数。如果不是 0,则需要手工检查僵尸进程
int zombie_tasks = 0;
};
struct TOP3CPUInfo
{
// %Cpu(s): 0.1 us 用户模式占用的 CPU 百分比
double percent_us = 0.0;
// 0.1 sy 系统模式占用的 CPU 百分比
double percent_sy = 0.0;
// 0.0 ni 改变过优先级的用户进程占用的 CPU 百分比
double percent_ni = 0.0;
// 99.7 id 空闲 CPU 占用的 CPU 百分比
double percent_id = 0.0;
// 0.1 wa 等待输入/输出的进程占用的 CPU 百分比
double percent_wa = 0.0;
// 0.0 hi 硬中断请求服务占用的 CPU 百分比
double percent_hi = 0.0;
// 0.1 si 软中断请求服务占用的 CPU 百分比
double percent_si = 0.0;
// 0.0 st st(steal time)意为虚拟时间百分比,就是当有虚拟机时,虚拟 CPU 等待实际 CPU 的时间百分比
double percent_st = 0.0;
};
struct TOP4MemoryInfo
{
// KiB Mem : 16334368 total, 物理内存的总量,单位为KB
double memery_total = 0.0;
// 4251264 free, 空闲的物理内存数量
double memery_free = 0.0;
// 5003964 used, 己经使用的物理内存数量
double memery_used = 0.0;
// 7079140 buff/cache 作为缓冲的内存数量
double memery_buff_cache = 0.0;
};
struct TOP5SwapInfo
{
// KiB Swap: 31249404 total, 交换分区(虚拟内存)的总大小
double swap_total = 0.0;
// 30703044 free, 空闲交换分区的大小
double swap_free = 0.0;
// 546360 used. 已经使用的交换分区的大小
double swap_used = 0.0;
// 10721664 avail Mem 作为缓存的交换分区的大小
double swap_available = 0.0;
};
struct TOP6ProcessInfo
{
public:
// PID:进程的 ID。
int process_PID = 0;
// USER:该进程所属的用户。
std::string process_USER = "";
// PR:优先级,数值越小优先级越高。
std::string process_PR = "";
// NI:Nice值的范围从-20到+19(不同系统的值范围是不一样的),
// 正值表示低优先级,负值表示高优先级,值为零则表示不会调整该进程的优先级。
int process_NI = 0;
// VIRT:进程使用的虚拟内存总量,单位kb。VIRT=SWAP+RES
double process_VIRT = 0;
// RES:进程使用的、未被换出的物理内存大小,单位kb。RES=CODE+DATA
double process_RES = 0;
// SHR:共享内存大小,单位为 KB。
double process_SHR = 0;
// S:进程状态。D=不可中断的睡眠状态 R=运行 S=睡眠 T=跟踪/停止 Z=僵尸进程
std::string process_S = "";
// %CPU:该进程占用 CPU 的百分比。
double process_percentageCPU = 0.0;
// %MEM:该进程占用内存的百分比。
double process_percentageMEM = 0.0;
// TIME+:该进程共占用的 CPU 时间。
std::string process_TIMEPlus = "";
// COMMAND:进程的命令名。
std::string process_COMMAND = "";
};
class TOPParser
{
public:
TOPParser(std::string top_shell_cmd);
bool updateAllInfo();
std::list<TOP6ProcessInfo> getAllProcessInfo();
TOP1HeaderInfo getHeaderInfo();
private:
void executeCMD(const char *cmd, char *result);
bool update1HeaderInfo(std::string str_info);
bool update2TasksInfo(std::string str_info);
bool update3CPUInfo(std::string str_info);
bool update4MemoryInfo(std::string str_info);
bool update5SwapInfo(std::string str_info);
bool update6ProcessInfo(std::string str_info);
private:
std::string m_top_shell_cmd = "";
TOP1HeaderInfo m_1header_info;
TOP2TasksInfo m_2tasks_info;
TOP3CPUInfo m_3cpu_info;
TOP4MemoryInfo m_4memory_info;
TOP5SwapInfo m_5swap_info;
std::list<TOP6ProcessInfo> m_list_6process_info;
};
TOPParser::TOPParser(std::string top_shell_cmd)
: m_top_shell_cmd(top_shell_cmd)
{
}
std::list<TOP6ProcessInfo> TOPParser::getAllProcessInfo()
{
return m_list_6process_info;
}
TOP1HeaderInfo TOPParser::getHeaderInfo()
{
return m_1header_info;
}
bool TOPParser::updateAllInfo()
{
char result[10000] = "";
executeCMD(m_top_shell_cmd.c_str(), result);
std::string result_shell(result);
// std::cout << result_shell << std::endl;
// 寻找第二个top信息块的位置
size_t index0 = result_shell.find("top - ", 0);
size_t index1 = result_shell.find("top - ", ++index0);
size_t index2 = result_shell.find("top - ", ++index1);
// std::cout << "index0:" << index0 << " index1:" << index1 << " index2:" << index2 << std::endl;
if (index0 == std::string::npos ||
index1 == std::string::npos ||
index2 == std::string::npos)
{
return false;
}
// 获取第二个top信息块字符串
std::string str_tmp2 = result_shell.substr(index1 - 1, index2 - index1 + 1);
// std::cout << str_tmp2 << std::endl
// << "updateAllInfo------------" << std::endl;
return (update6ProcessInfo(str_tmp2) &&
update1HeaderInfo(str_tmp2) &&
update2TasksInfo(str_tmp2) &&
update3CPUInfo(str_tmp2) &&
update4MemoryInfo(str_tmp2) &&
update5SwapInfo(str_tmp2));
}
bool TOPParser::update1HeaderInfo(std::string str_info)
{
size_t index0 = str_info.find("top - ", 0);
size_t index1 = str_info.find("\n", index0);
if (index0 != std::string::npos &&
index1 != std::string::npos)
{
std::string str_1header_info = str_info.substr(index0, index1 - index0 + 1);
// std::cout << str_1header_info << std::endl
// << "update1HeaderInfo---------";
int ret = sscanf(str_1header_info.c_str(),
"top - %d:%d:%d up %d days, %d:%d, %d users, load average: %lf, %lf, %lf",
&m_1header_info.system_time_hh,
&m_1header_info.system_time_mm,
&m_1header_info.system_time_ss,
&m_1header_info.system_runing_time_dd,
&m_1header_info.system_runing_time_hh,
&m_1header_info.system_runing_time_mm,
&m_1header_info.num_users,
&m_1header_info.load_average_1minuts,
&m_1header_info.load_average_5minuts,
&m_1header_info.load_average_15minuts);
// std::cout << m_1header_info.system_time_hh << " "
// << m_1header_info.system_time_mm << " "
// << m_1header_info.system_time_ss << " "
// << m_1header_info.system_runing_time_dd << " "
// << m_1header_info.system_runing_time_hh << " "
// << m_1header_info.system_runing_time_mm << " "
// << m_1header_info.num_users << " "
// << m_1header_info.load_average_1minuts << " "
// << m_1header_info.load_average_5minuts << " "
// << m_1header_info.load_average_15minuts << " "
// << std::endl;
if (ret != 10)
{
return false;
}
}
else
{
std::cerr << "update1HeaderInfo(): failed" << std::endl;
return false;
}
return true;
}
bool TOPParser::update2TasksInfo(std::string str_info)
{
size_t index0 = str_info.find("Tasks:", 0);
size_t index1 = str_info.find("\n", index0);
if (index0 != std::string::npos &&
index1 != std::string::npos)
{
std::string str_2tasks_info = str_info.substr(index0, index1 - index0 + 1);
// std::cout << str_2tasks_info << std::endl
// << "update2TasksInfo-------------";
int ret = sscanf(str_2tasks_info.c_str(),
"Tasks: %d total, %d running, %d sleeping, %d stopped, %d zombie",
&m_2tasks_info.total_tasks,
&m_2tasks_info.running_tasks,
&m_2tasks_info.sleeping_tasks,
&m_2tasks_info.stopped_tasks,
&m_2tasks_info.zombie_tasks);
// std::cout << m_2tasks_info.total_tasks << " "
// << m_2tasks_info.running_tasks << " "
// << m_2tasks_info.sleeping_tasks << " "
// << m_2tasks_info.stopped_tasks << " "
// << m_2tasks_info.zombie_tasks << " "
// << std::endl;
if (ret != 5)
{
std::cout << "ret:" << ret << std::endl;
return false;
}
return true;
}
else
{
std::cerr << "update2TasksInfo(): failed" << std::endl;
return false;
}
}
bool TOPParser::update3CPUInfo(std::string str_info)
{
size_t index0 = str_info.find("\%Cpu(s):", 0);
size_t index1 = str_info.find("\n", index0);
if (index0 != std::string::npos &&
index1 != std::string::npos)
{
std::string str_3cpu_info = str_info.substr(index0, index1 - index0 + 1);
// std::cout << str_3cpu_info << std::endl
// << "update3CPUInfo------------";
int ret = sscanf(str_3cpu_info.c_str(),
"%%Cpu(s): %lf us, %lf sy, %lf ni, %lf id, %lf wa, %lf hi, %lf si, %lf st",
&m_3cpu_info.percent_us,
&m_3cpu_info.percent_sy,
&m_3cpu_info.percent_ni,
&m_3cpu_info.percent_id,
&m_3cpu_info.percent_wa,
&m_3cpu_info.percent_hi,
&m_3cpu_info.percent_si,
&m_3cpu_info.percent_st);
// std::cout << m_3cpu_info.percent_us << " "
// << m_3cpu_info.percent_sy << " "
// << m_3cpu_info.percent_ni << " "
// << m_3cpu_info.percent_id << " "
// << m_3cpu_info.percent_wa << " "
// << m_3cpu_info.percent_hi << " "
// << m_3cpu_info.percent_si << " "
// << m_3cpu_info.percent_st << " "
// << std::endl;
if (ret != 8)
{
return false;
}
}
else
{
std::cerr << "update3CPUInfo(): failed" << std::endl;
return false;
}
return true;
}
bool TOPParser::update4MemoryInfo(std::string str_info)
{
size_t index0 = str_info.find("KiB Mem :", 0);
size_t index1 = str_info.find("\n", index0);
if (index0 != std::string::npos &&
index1 != std::string::npos)
{
std::string str_4memory_info = str_info.substr(index0, index1 - index0 + 1);
// std::cout << str_4memory_info << std::endl
// << "update4MemoryInfo----------" << std::endl;
int ret = sscanf(str_4memory_info.c_str(),
"KiB Mem : %lf total, %lf free, %lf used, %lf buff/cache",
&m_4memory_info.memery_total,
&m_4memory_info.memery_free,
&m_4memory_info.memery_used,
&m_4memory_info.memery_buff_cache);
// std::cout << m_4memory_info.memery_total << " "
// << m_4memory_info.memery_free << " "
// << m_4memory_info.memery_used << " "
// << m_4memory_info.memery_buff_cache << " "
// << std::endl;
if (ret != 4)
{
return false;
}
return true;
}
else
{
std::cerr << "update4MemoryInfo(): failed" << std::endl;
return false;
}
}
bool TOPParser::update5SwapInfo(std::string str_info)
{
size_t index0 = str_info.find("KiB Swap:", 0);
size_t index1 = str_info.find("\n", index0);
if (index0 != std::string::npos &&
index1 != std::string::npos)
{
std::string str_5swap_info = str_info.substr(index0, index1 - index0 + 1);
// std::cout << str_5swap_info << std::endl
// << "update5SwapInfo"
// << "----------------" << std::endl;
int ret = sscanf(str_5swap_info.c_str(),
"KiB Swap: %lf total, %lf free, %lf used. %lf avail Mem",
&m_5swap_info.swap_total,
&m_5swap_info.swap_free,
&m_5swap_info.swap_used,
&m_5swap_info.swap_available);
// std::cout << m_5swap_info.swap_total << " "
// << m_5swap_info.swap_free << " "
// << m_5swap_info.swap_used << " "
// << m_5swap_info.swap_available << " "
// << std::endl;
if (ret != 4)
{
return false;
}
}
else
{
std::cerr << "update5SwapInfo(): failed" << std::endl;
return false;
}
return true;
}
bool TOPParser::update6ProcessInfo(std::string str_info)
{
// 寻找目标字符串中进程信息的行数(依据状态符号:D、R、S、T、Z五种状态)
size_t index_D = 0;
std::list<size_t> list_indexes;
while ((index_D = str_info.find(" D ", index_D)) != std::string::npos)
{
list_indexes.push_back(index_D);
index_D++;
}
//
size_t index_R = 0;
while ((index_R = str_info.find(" R ", index_R)) != std::string::npos)
{
list_indexes.push_back(index_R);
index_R++;
}
//
size_t index_S = 0;
while ((index_S = str_info.find(" S ", index_S)) != std::string::npos)
{
list_indexes.push_back(index_S);
index_S++;
}
//
size_t index_T = 0;
while ((index_T = str_info.find(" T ", index_T)) != std::string::npos)
{
list_indexes.push_back(index_T);
index_T++;
}
//
size_t index_Z = 0;
while ((index_Z = str_info.find(" Z ", index_Z)) != std::string::npos)
{
list_indexes.push_back(index_Z);
index_Z++;
}
//
if (list_indexes.size() == 0)
{
return false;
}
// 逐行解析
for (auto index : list_indexes)
{
// 获得第index所在的行字符串
size_t index_tmp = str_info.find("\n", index);
std::string str_6process_info = str_info.substr(index - 44, index_tmp - (index - 44) + 1);
// 解析该行字符串
TOP6ProcessInfo process_info;
std::istringstream iss(str_6process_info);
iss >> process_info.process_PID;
iss >> process_info.process_USER;
iss >> process_info.process_PR;
iss >> process_info.process_NI;
// read VIRT
std::string str_tmp;
str_tmp.clear();
iss >> str_tmp;
index = str_tmp.find("g", 0);
if (index == std::string::npos) // 无字母g时
{
process_info.process_VIRT = atof(str_tmp.c_str());
}
else // 有字母g时
{
str_tmp = str_tmp.substr(0, str_tmp.size() - 1);
process_info.process_VIRT = atof(str_tmp.c_str()) * 1024.0 * 1024.0;
}
// read RES
str_tmp.clear();
iss >> str_tmp;
index = str_tmp.find("g", 0);
if (index == std::string::npos) // 无字母g时
{
process_info.process_RES = atof(str_tmp.c_str());
}
else // 有字母g时
{
str_tmp = str_tmp.substr(0, str_tmp.size() - 1);
process_info.process_RES = atof(str_tmp.c_str()) * 1024.0 * 1024.0;
}
// read SHR
str_tmp.clear();
iss >> str_tmp;
index = str_tmp.find("g", 0);
if (index == std::string::npos) // 无字母g时
{
process_info.process_SHR = atof(str_tmp.c_str());
}
else // 有字母g时
{
str_tmp = str_tmp.substr(0, str_tmp.size() - 1);
process_info.process_SHR = atof(str_tmp.c_str()) * 1024.0 * 1024.0;
}
//
iss >> process_info.process_S;
iss >> process_info.process_percentageCPU;
iss >> process_info.process_percentageMEM;
iss >> process_info.process_TIMEPlus;
iss >> process_info.process_COMMAND;
// std::cout << process_info.process_PID << " "
// << process_info.process_USER << " "
// << process_info.process_PR << " "
// << process_info.process_NI << " "
// << process_info.process_VIRT << " "
// << process_info.process_RES << " "
// << process_info.process_SHR << " "
// << process_info.process_S << " "
// << process_info.process_percentageCPU << " "
// << process_info.process_percentageMEM << " "
// << process_info.process_TIMEPlus << " "
// << process_info.process_COMMAND << std::endl;
m_list_6process_info.push_back(process_info);
}
return true;
}
void TOPParser::executeCMD(const char *cmd, char *result)
{
char buf_ps[1024];
char ps[1024] = {0};
FILE *ptr;
strcpy(ps, cmd);
if ((ptr = popen(ps, "r")) != NULL)
{
while (fgets(buf_ps, 1024, ptr) != NULL)
{
strcat(result, buf_ps);
if (strlen(result) > 10000)
break;
}
pclose(ptr);
ptr = NULL;
}
else
{
printf("popen %s error\n", ps);
}
}
int main(int argc, char **argv)
{
// 关于str_user_defined的制定,参考【正则表达式】即可
// std::string str_user_defined = "sunloginc"; //[ok] 在top输出中查找包含字符串sunloginclient的行
// std::string str_user_defined = "\\<sunloginclient\\>"; //[ok] 在top输出中精确查找包含单词sunloginclient的行
// std::string str_user_defined = "sun|top"; //[ok] 在top输出中查找包含字符串sun或字符串top的行
// std::string str_user_defined = "jackie.*?sun"; //[ok] 查找同时包含字符串[jackie.*?sun]的行,[.*?]表示任意多个任意字符
std::string str_user_defined = "\\<front_end_node\\>"; //[ok] 在top输出中精确查找包含单词sunloginclient的行
std::string top_shell_cmd = "top -n 3 -b | grep -E \"top - |Tasks:|\%Cpu|KiB Mem :|KiB Swap:|" + //与解析代码相对应,不要修改
str_user_defined + // 根据评估进程的不同,按格式修改
std::string("\""); // 不要修改
while (1)
{
TOPParser reader(top_shell_cmd);
// std::chrono::steady_clock::time_point t1 = std::chrono::steady_clock::now();
if (reader.updateAllInfo())
{
auto all_process_info = reader.getAllProcessInfo();
double sum_CPU = 0.0;
double sum_MEM = 0.0;
double sum_RES = 0.0;
for (auto pi : all_process_info)
{
if (pi.process_USER == "jackie")
{
sum_CPU += pi.process_percentageCPU;
sum_MEM += pi.process_percentageMEM;
sum_RES += pi.process_RES;
}
}
auto header = reader.getHeaderInfo();
std::cout << "system time:" << header.system_time_hh << ":" << header.system_time_mm << ":" << header.system_time_ss
<< " \tCPU:" << sum_CPU
<< "% \tMEM:" << sum_MEM
<< "% \tRES:" << sum_RES / 1024.0 << "MB" << std::endl;
}
// std::chrono::steady_clock::time_point t2 = std::chrono::steady_clock::now();
// std::chrono::duration<double> time_used = std::chrono::duration_cast<std::chrono::duration<double>>(t2 - t1);
// std::cout << "time used(s):" << time_used.count() << std::endl;
}
return 0;
}
测试部分:ok
jackie@jackie-lenovo:~/WS_Source/learn_cpp/05-cpu_usage/build$ ./main
system time:16:1:12 CPU:26.2% MEM:1.7% RES:270.555MB
system time:16:1:18 CPU:25.9% MEM:1.7% RES:270.469MB
system time:16:1:25 CPU:25.2% MEM:1.7% RES:270.414MB
system time:16:1:31 CPU:20.9% MEM:1.9% RES:307.707MB
system time:16:1:37 CPU:19.9% MEM:1.9% RES:307.309MB
system time:16:1:43 CPU:22.3% MEM:1.7% RES:270.316MB
system time:16:1:49 CPU:21.6% MEM:1.7% RES:270.496MB
system time:16:1:56 CPU:19.6% MEM:1.7% RES:270.672MB
system time:16:2:2 CPU:19.6% MEM:1.7% RES:270.766MB
...
以上为C++解析输出结果(更新周期约为6.2s)
jackie@jackie-lenovo:~$ top -b | grep -E "front"
10057 jackie 20 0 837688 276868 33956 S 19.3 1.7 6:07.08 front_end_node
10057 jackie 20 0 853372 276988 33956 S 25.9 1.7 6:07.86 front_end_node
10057 jackie 20 0 853512 277076 33956 S 19.9 1.7 6:08.46 front_end_node
10057 jackie 20 0 861512 277168 33956 S 19.6 1.7 6:09.05 front_end_node
10057 jackie 20 0 861628 277220 33956 S 15.6 1.7 6:09.52 front_end_node
10057 jackie 20 0 834268 277264 33956 S 19.7 1.7 6:10.11 front_end_node
...
以上为shell命令输出结果(更新周期默认约为3s)
使用说明
- 第一步:通过top查看想要评估效率的程序的命令和其他特点;
- 第二步:书写适当的正则表达式;
- 第三步:修改源代码,包括shell命令、适当打数据处理、输出到的目标文件等;
注意事项
:程序更新周期约为6.2秒,它仅作为单独的程序性能评估软件使用,请勿将其写入到你的任务程序当中。
参考资料
- C/C++ 程序中调用命令行命令并获取命令行输出结果【我的程序的核心代码,非常感谢这位博主】
- grep 命令系列:grep 中的正则表达式【正则表达式这部分还是比较通用的】
- C++获取对应进程的cpu和内存使用情况(支持linux和windows)【当代码中周期改为3s时,结果于top近似,但需手动指定PID,使用起来不太方便】
- rqt_top【专门面向ROS节点的性能检测软件】
标签:20,
0.0,
top,
jackie,
内存,
str,
Linux,
CPU
From: https://www.cnblogs.com/jackie2455/p/16769389.html