前言: 在前嵌入式开发中,往往需要考虑占用内存大小以及CPU的占用率。所以我们在写好程序后,就需要进行测试,防止出现CPU使用率过高以及内存占用过大,导致程序不能运行的问题,下面就介绍一种简单通用的办法来实现这些功能。

第一步

在Linux环境下的线程其实就是轻量级的进程,但是我们通过top 或 ps -aux 命令一般都是查不到具体的线程号tid,需要在各个线程实现代码中获取线程ID。
具体实现如下:

#include<sys/syscall.h>

pid_t getId()
{
return syscall(SYS_getId);
}

第二步

通过线程ID可以获取各线程的CPU使用率。
具体分析如下:
使用如下指令进行查看

cat /proc/<pid>/task/<tid>/stat

为程序的PID,为程序的各个线程的ID号,stat文件就是一些调度信息。
例如:

cat
每个参数意思为:
参数 解释
pid=6873 进程(包括轻量级进程,即线程)号
comm=a.out 应用程序或命令的名字
task_state=R 任务的状态,R:runnign, S:sleeping (TASK_INTERRUPTIBLE), D:disk sleep (TASK_UNINTERRUPTIBLE), T: stopped, T:tracing stop,Z:zombie, X:dead
ppid=6723 父进程ID
pgid=6873 线程组号
sid=6723 该任务所在的会话组ID
tty_nr=34819(pts/3) 该任务的tty终端的设备号,INT(34817/256)=主设备号,(34817-主设备号)=次设备号
tty_pgrp=6873 终端的进程组号,当前运行在该任务所在终端的前台任务(包括shell 应用程序)的PID。
task->flags=8388608 进程标志位,查看该任务的特性
min_flt=77 该任务不需要从硬盘拷数据而发生的缺页(次缺页)的次数
cmin_flt=0 累计的该任务的所有的waited-for进程曾经发生的次缺页的次数目
maj_flt=0 该任务需要从硬盘拷数据而发生的缺页(主缺页)的次数
cmaj_flt=0 累计的该任务的所有的waited-for进程曾经发生的主缺页的次数目
utime=1587 该任务在用户态运行的时间,单位为jiffies
stime=1 该任务在核心态运行的时间,单位为jiffies
cutime=0 累计的该任务的所有的waited-for进程曾经在用户态运行的时间,单位为jiffies
cstime=0 累计的该任务的所有的waited-for进程曾经在核心态运行的时间,单位为jiffies
priority=25 任务的动态优先级
nice=0 任务的静态优先级
num_threads=3 该任务所在的线程组里线程的个数
it_real_value=0 由于计时间隔导致的下一个 SIGALRM 发送进程的时延,以 jiffy 为单位.
start_time=5882654 该任务启动的时间,单位为jiffies
vsize=1409024(page) 该任务的虚拟地址空间大小
rss=56(page) 该任务当前驻留物理地址空间的大小
Number of pages the process has in real memory,minu 3 for administrative purpose.
这些页可能用于代码,数据和栈。
rlim=4294967295(bytes) 该任务能驻留物理地址空间的最大值
start_code=134512640 该任务在虚拟地址空间的代码段的起始地址
end_code=134513720 该任务在虚拟地址空间的代码段的结束地址
start_stack=3215579040 该任务在虚拟地址空间的栈的结束地址
kstkesp=0 esp(32 位堆栈指针) 的当前值, 与在进程的内核堆栈页得到的一致.
kstkeip=2097798 指向将要执行的指令的指针, EIP(32 位指令指针)的当前值.
pendingsig=0 待处理信号的位图,记录发送给进程的普通信号
block_sig=0 阻塞信号的位图
sigign=0 忽略的信号的位图
sigcatch=082985 被俘获的信号的位图
wchan=0 如果该进程是睡眠状态,该值给出调度的调用点
nswap 被swapped的页数,当前没用
cnswap 所有子进程被swapped的页数的和,当前没用
exit_signal=17 该进程结束时,向父进程所发送的信号
task_cpu(task)=0 运行在哪个CPU上
task_rt_priority=0 实时进程的相对优先级别
task_policy=0 进程的调度策略,0=非实时进程,1=FIFO实时进程;2=RR实时进程

当线程比较多的时候一个线程一个线程去分析该文件比较费劲,可通过脚本一次解析完成,参数为进程PID,运行成功会输出该进程的所有线程tid,用户层CPU使用、内核态CPU使用,数值越高表示消耗CPU资源越多。
编写如下脚本stat.sh

#!/bin/sh
#get /proc/pid/task/tid/stat
#$1 is tid
#$14 is user cpu
#$15 is sys cpu
echo "tid user sys"
for file in /proc/$1/task/*
do
if test -d $file
then
cat $file/stat | awk -F" " '{print $1 " " $14 " " $15}'
fi
done

linux 环境下运行脚本

介于有很多人不知道怎么在Linux下使用脚本,也在这里简单的介绍一下,具体学习你转学其他学习资料。
Linux自带脚本,可以自己运行脚本的编写工作。

  • 第一步
    新建一个文件stat.sh.具体命令如下:
touch
  • 第二步
    进入编辑,具体命令如下:
vim stat.sh
  • 第三步
    将上面代码赋值进去
  • 第四步
    修改stat.sh的权限,为了赋予可执行权限,我这全都赋予了,具体根据你的情况而定。使用如下命令:
chmod
  • 第五步
    执行脚本即可
./stat.sh

至此一个线程CPU查看就完事,有需要的可以试一下,大大提高效率,喜欢的点个赞吧。