Linux多线程6:多线程调试与优化

798次阅读
没有评论

gdb基础用法:https://www.daodaodao123.com/?p=665

1.gdb与多线程

案例代码:

#include <stdio.h>
#include <pthread.h>
#include <sys/types.h>
#include <signal.h>

struct thread_param
{
    char info;
    int num;
    int delay;
};

void* thread_fun(void* param)
{
    struct thread_param* p;

    p=(struct thread_param*)param;
    int i;

    printf("thread pid:%d, tid:%lu\n",getpid(), pthread_self());
    for(i=0;i<p->num;i++){

#if  0 /* change to #if 1 for debugging high cpu-loading issues */
        while(1);
#else
        sleep(p->delay);
#endif
        printf("%i: %c\n",i,p->info);
    }

    return NULL;
}

int main(void)
{
    pthread_t tid1,tid2;
    struct thread_param info1;
    struct thread_param info2;
    int ret;

    printf("main pid:%d, tid:%lu\n",getpid(), pthread_self());

    info1.info='T';
    info1.num=2000000;
    info1.delay=1;
    ret=pthread_create(&tid1,NULL,thread_fun,&info1);
    if(ret==-1){
        perror("cannot create new thread");
        return 1;
    }

    info2.info='S';
    info2.num=300000;
    info2.delay=2;
    ret=pthread_create(&tid2,NULL,thread_fun,&info2);
    if(ret==-1){
        perror("cannot create new thread");
        return 1;
    }

    if(pthread_join(tid1,NULL)!=0){
        perror("call pthread_join function fail");
        return 1;
    }

    if(pthread_join(tid2,NULL)!=0){
        perror("call pthread_join function fail");
        return 1;
    }

    return 0;
}   

1.1 查看指定线程信息

i threads

查看所有线程的backtrace,针对coredump文件,用该命令查看程序宕机时,每个线程具体执行到那个地方;

thread apply all bt 

查看线程1的backtrace

thread apply 1 bt 

Linux多线程6:多线程调试与优化

1.2 设置断点

(1)默认情况下,断点对所有线程有效

b 28

Linux多线程6:多线程调试与优化

(2)设定断点读特定线程有效

b 28 thread 2

1.3 单独运行某个线程

thread 2
set scheduler-locking on
#取消锁定
set scheduler-locking off

Linux多线程6:多线程调试与优化
性能分析源码:

#include <pthread.h>

func_d()
{
    int i;
    for(i=0;i<50000;i++);
}

func_a()
{
    int i;
    for(i=0;i<100000;i++);
    func_d();
}

func_b()
{
    int i;
    for(i=0;i<200000;i++);
}

func_c()
{
    int i;
    for(i=0;i<300000;i++);
}

void* thread_fun1(void* param)
{
    while(1) {
        int i;
        for(i=0;i<100000;i++);

        func_a();
        func_b();
        func_c();
    }
}

void* thread_fun2(void* param)
{
    while(1) {
        int i;
        for(i=0;i<100000;i++);

        func_a();
        func_b();
        func_c();
    }
}

int main(void)
{
    pthread_t tid1,tid2;
    int ret;

    ret=pthread_create(&tid1,NULL,thread_fun1,NULL);
    if(ret==-1){
        perror("cannot create new thread");
        return 1;
    }

    ret=pthread_create(&tid2,NULL,thread_fun2,NULL);
    if(ret==-1){
        perror("cannot create new thread");
        return 1;
    }

    if(pthread_join(tid1,NULL)!=0){
        perror("call pthread_join function fail");
        return 1;
    }

    if(pthread_join(tid2,NULL)!=0){
        perror("call pthread_join function fail");
        return 1;
    }

    return 0;
}   

编译

$ gcc -g test.c  -lpthread  

2.Intel平台多线程性能分析工具:Intel VTune Profiler

https://www.intel.com/content/www/us/en/developer/tools/oneapi/vtune-profiler.html#gs.qcqcrv

3.perf

(1)采样

sudo perf recored -s ./a.out  //生成perf.data文件

(2)分析采样数据

sudo perf report -n -T  //分析采样数据,包括所有线程
sudo perf report -n -T --tid xxxx  //分析指定线程xxxx cpu 消耗

(3)perf录制,生成火焰图

perf recore -F 99 -a -g -- ./a.out
perf script | ../stackcollapse-perf.pl > out.perf-folded
../flamegraph.pl out.perf-fouded > perf-kernel.svg

firefox perf-kernel.svg

4.valgrind

(1)采集数据

valgrind --tool=callgrind --separate-threads=yes ./a.out

生成如下文件:
callgrind.out.4427 进程级的数据,包括所有线程
callgrind.out.4427-01 //特定线程的数据
callgrind.out.4427-02
callgrind.out.4427-03

(2)用图形化工具kcachegrinkcache查看分析数据
查看整个进程级数据

kcachegrinkcache  callgrind.out.4427

Linux多线程6:多线程调试与优化

查看线程2数据
Linux多线程6:多线程调试与优化

注:在嵌入式中,可以在设备端用valgrind采集数据,在PC端用kcachegrinkcache图像化工具查看分析;

5 top命令

(1)top 进程视角
(2)top -H 线程视角
按1, 显示多个核信息
Linux多线程6:多线程调试与优化

(3)只查看指定线程信息

top -H  -p `pidof a.out`

Linux多线程6:多线程调试与优化

(4)按“f”可以配置显示信息
Linux多线程6:多线程调试与优化

(5)htop增强型的线程视角

htop -p `pidof a.out`

Linux多线程6:多线程调试与优化

(6)用perf录像

sudo perf sched record -a sleep 20

生成perf.data

sudo perf timechart

生成矢量图,用firefox查看

firefox output.svg

正文完
 0
admin
版权声明:本站原创文章,由 admin 于2022-02-25发表,共计3102字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)
粤ICP备2021172357号-1