做人呢,最紧要就系开心啦

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

779次阅读
没有评论

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

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