3-Linux 进程中的某个线程占用时间

在比较大型的项目中,通常都会使用多线程技术,而且通常是多人合作开发,各方自测OK之后,整合在一起往往会出现一些问题,CPU使用率过高就是其中之一。如何在不熟悉所有模块代码的情况下,快速的定位到具体哪一个线程在消耗CPU,显得很有必要。在X86上,可以借助一些工具进行定位分析,但是在嵌入式系统中,工具就比较匮乏,各命令功能也比较简单,就不好定位。

现介绍一种简单通用的办法:

1.获取各个线程的tid

ps查看进程

root@zihome:/proc/2111# ps | grep ZGateway
 2111 root     76112 S    {MainThread} /zihome/plugins/zgateway/ZGateway /dev/ttyS2 /dev/ttyS1
 2114 root      1520 S    {ZGatewayTimerCh} /bin/sh /zihome/plugins/zgateway/ZGatewayTimerCheck.sh /zihome/plugins/zgateway/run.sh
12072 root      1520 S    grep ZGateway

然后在proc/$pid/task/下面可以看到所有线程

root@zihome:/proc/2111/task# ls
2111  2139  2670  2697  2730  2733  2743  2748  2781  2790  2793  2803  2806
2133  2140  2695  2698  2731  2741  2744  2779  2788  2791  2794  2804
2135  2669  2696  2728  2732  2742  2746  2780  2789  2792  2802  2805

有37个,但是我们不知道每个线程对应的是代码里面的哪个线程,这就需要我们在代码里面添加线程号tid的获取,在代码里面将线程号和线程名字对应上。

+#include <sys/syscall.h>
+#define gettid() syscall(SYS_gettid)

在代码线程的main函数里面添加gettid进行打印

printf("\n%s Thread id : gettid() == %d\n",__FUNCTION__,gettid());

这样就知道tid对应的线程名称

2.获取线程CPU运行时间
[root@localhost ~]# cat /proc/6873/stat
6873 (a.out) R 6723 6873 6723 34819 6873 8388608 77 0 0 0 41958 31 0 0 25 0 3 0 5882654 1409024 56 4294967295 134512640 134513720 3215579040 0 2097798 0 0 0 0 0 0 0 17 0 0 0 [root@localhost ~]#
每个参数意思为:
参数                                                       解释
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实时进程

编写获取所有线程tid、用户层CPU使用、内核态CPU使用,数值越高表示消耗CPU资源越多get_tid_cpu.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
root@zihome:/zihome/plugins# ./get_tid_cpu.sh 11598
tid user sys
11598 48 187
11621 6 7
11622 109 17
11623 0 0
11624 0 0
11723 1 1
11724 9 0
11742 3 1
11743 0 0
11744 4 1
11745 0 0
11758 2 1
11759 0 0
11760 0 1
11761 1 0
11762 0 0
11764 1 0
11767 0 2
11768 0 0
11770 0 0
11771 0 0
11772 0 0
11787 182 8
11810 0 5
11811 5 0
11812 3 1
11819 1 3
11820 0 0
11821 0 1
11822 0 0
11823 0 0
11824 5 2
11826 0 0
11833 7 6
11834 1 0
11835 0 0
11836 0 2
11837 0 1

tid user sys
11598 71 191
11621 25 53
11622 214 23
11724 21 3
11742 24 8
11744 49 9
11745 7 3
11758 9 13
11787 1410 33
11810 3 12
11811 7 14
11812 4 3
11819 2 4
11820 7 0
11821 18 12
11822 5 7
11824 18 10
11826 3 3
11833 17 49
11834 9 17
11836 10 15


HttpWrapper Thread id : gettid() == 11622
DeviceMultipleService Thread id : gettid() == 11623
MqttManager Thread id : gettid() == 11723
DusunZigbeeController Thread id : gettid() == 11744
handleSendUbusData Thread id : gettid() == 11745
mqttHandlerConnect Thread id : gettid() == 11758       
parseUdpBroadcast Thread id : gettid() == 11759
handleSendUartData Thread id : gettid() == 11762
handleUartData Thread id : gettid() == 11761
HaierController Thread id : gettid() == 11826
expireThread Thread id : gettid() == 11834
handleMessage Thread id : gettid() == 11835

定位具体线程,分析什么原因导致cpu使用率高

嵌入式linux下线程CPU占用跟踪: https://blog.csdn.net/wofeile880_jian/article/details/77584842

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值