使用 perf 或其他工具分析等待线程

问题描述 投票:0回答:0

在多线程程序中,如何有效地分析等待锁、休眠或以其他方式调度的线程?

为了我的分析目的,我需要深入了解一些锁争用。所以我想在例如堆栈跟踪分析器工具中看到这一点,可以从中生成火焰图。我首先尝试使用 gperftools CPU 分析器来做到这一点。但顾名思义,它只会分析实际上在 CPU 上执行某些操作的线程,您不会看到等待锁的线程的堆栈跟踪。

然后我切换到 perf,我希望它足够强大,能够以某种方式收集计划外线程的配置文件信息。但到目前为止还没有运气。

这是我的测试程序:

#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

const int NR_THREADS = 8;
const int DURATION   = 5;

bool done = false;

struct thread_data_t {
    pthread_t thread;
    pthread_mutex_t* mutex;
    int tid;
};

void *threadfunction(void *arg)
{

    pthread_mutex_t* mutex  =  arg;

    pthread_mutex_lock(mutex);
    printf("I am the thread function!\n");
    pthread_mutex_unlock(mutex);
}

int main(void)
{
    pthread_mutex_t mutex;
    pthread_mutex_init(&mutex, 0);
    pthread_mutex_lock(&mutex);

    pthread_t thread;
    (void) pthread_create(&thread, NULL, threadfunction, &mutex);
    
    for (int i = 0; i < 60000000; i++)
        printf("I am the main function!\n");

    pthread_mutex_unlock(&mutex);

    (void) pthread_join(thread, NULL);

    return 0;
}

现在我运行以下性能记录

perf record -F50  --call-graph dwarf test_program

我将其编译成火焰图

perf script > perf.script
stackcollapse-perf.pl perf.script | flamegraph.pl > flamegraph.svg

生成的火焰图如下。而且你可以看到它基本上只显示了属于 main 函数的堆栈。 threadfunction 在不同的线程中运行,因为它正在等待锁定并因此被调度,你看不到任何与之相关的堆栈跟踪。

我尝试将某些事件添加到perf-record

-e sched:sched_stat_sleep,sched:sched_switch

但这也没有帮助。

我如何使用 perf 有效地创建和编译基于锁争用的堆栈跟踪配置文件和基于 CPU 的堆栈跟踪配置文件?我喜欢使用 perf,但我也非常愿意接受其他工具建议。

例如,据我所知,使用基于gdb穷人分析器,您实际上可以获得休眠线程的堆栈跟踪。这是合理的,因为 gdb 必须能够以某种方式从任何线程获取堆栈信息。但是我更喜欢一个更协调和专用的工具来完成这样的任务 gdb.

谢谢!

c locking profiling perf gperftools
© www.soinside.com 2019 - 2024. All rights reserved.