百度内推,可文末扫码加微信
一、本文背景:
在多数情况下,尤其是基于Linux系统开发的软件,都是多线程模式的,而我们在开发的过程中是不会过多的关注线程资源的消耗问题,而是直接拿起函数就去调用,创建自己的任务,让它自己去玩。但是当遇到线程与线程间抢占资源的时候我们无从下手,不知道是怎么回事。本文做一个简单跟踪线程cpu消耗的介绍。
二、方法:
①首先我们要去抓取每个线程占用的资源,在linux服务器上可以用top -H 去查看,但是在嵌入式系统里我们用的是busybox,轻量级的top,不具有-H选项,所以我们只有另择他路。我们的办法是通过kernel自带的proc系统来获取,/proc/$PID/task/*/stat,stat文件中第14,15字段分别是代表的该线程用户空间占用的cpu时间,和内核空间占用的cpu时间,单位是jiffies。第1个字段是线程的PID值。有这三个参数我们就可以抓到是哪个线程占用的cpu时间较多。我们可以利用如下脚本内容在嵌入式设备上运行。
#!/bin/sh
#guoyb@startimes.com.cn
#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
执行完脚本输出的内容如下:
tid user sys
1654 0 0
1665 0 0
1666 0 0
1667 0 0
587 503 493
589 1 22
590 2 12
591 0 1
595 2 0
596 0 0
597 0 0
601 13 29
602 0 39
603 14 55
604 0 7
605 0 2
②通过以上输出的内容可以看到,输出只有tid user sys三项,虽然知道了哪个线程PID占用资源较高,但是却不知道具体是软件中哪个线程,所以这里我们要将PID与我们软件中的实际线程做关联对应起来。我们采用的方式很简单如下:
printf("\n%s Thread id : gettid() == %d\n",FUNCTION,syscall(SYS_gettid));
只需要在线程内部加入以上打印即可,syscall(SYS_gettid)可以获取该线程的PID值,这样与__FUNCTION__能够建立起对应关系。通过①中得到的PID可以查找到具体的线程函数。然后去具体的线程分析即可。
③通过以上方式加打印确定线程pid比较麻烦,当线程较多的时候需要一个一个去加打印,还有一个办法直接使用gdb来查看,gdb attach $PID(该命令可以关联进程号为PID的进程),然后输入bt(该命令可以显示出所有与该进程相关的堆栈内容,自然也会有其线程信息),即可看到线程名与其线程PID的对应关系,再由①中获取到的占用CPU较高的线程PID就可以找到对应的线程去分析来降低线程的消耗。
扫一扫,可加楼主微信,一起交流C语言,嵌入式等IT技术。
声明:本文原创,版权必究,编辑转载请注明链接出处与原作者。