linux下如何定位CPU过高问题

2019-03-16  本文已影响0人  小怪兽狂殴奥特曼

linux下如何定位CPU过高问题

1 先查看进程pid

ps aux | grep xxx

2 查看线程占用率情况

top -H -p pid
linux中的线程是一个轻量级进程,每个线程都有自己的pid。执行这个命令后可以看出占用率最高的线程的PID。
单看进程pid我们很难知道我们代码中的哪个线程出了问题,我们可以利用prctl(PR_SET_NAME, "xxx")给线程起名。至此我们通过线程名,大概可以猜到问题出现在哪个线程了。
然而还不够。

3 分析出问题的接口

strace -f -p PID
或者pstack PID
PID为上面的命令查看到的占用CPU最高的线程的PID。
之后可以看出调用最频繁的接口。

举个例子吧。这是一段C代码。

#include <pthread.h>
#include <stdio.h>
#include <sys/prctl.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/syscall.h>

void *thread_hndl1(void *arg)
{
        prctl(PR_SET_NAME, "thread_1");
        printf("i am thread_1 tid=0x%lx, pid=%d\n", 
              pthread_self(), syscall(SYS_gettid));
        while(1)
        {
                usleep(10);
        }
}
void *thread_hndl2(void *arg)
{
        prctl(PR_SET_NAME, "thread_2");
        printf("i am thread_2 tid=0x%lx, pid=%d\n", 
                    pthread_self(), syscall(SYS_gettid));
        while(1)
        {
                sleep(1);
        }
}

int main()
{
        pthread_t pid1,pid2;
        pthread_create(&pid1, NULL, thread_hndl1, NULL);
        pthread_create(&pid2, NULL, thread_hndl2, NULL);
        pthread_join(pid1, NULL);
        pthread_join(pid2, NULL);
}

先编译上面代码。

gcc -g -o debug_thread_mode debug_thread_mode.c -lpthread

运行程序

./debug_thread_mode

新开一个窗口,先查看debug_thread_mode的进程PID

ps aux | grep debug_thread_mode
捕获.PNG

进程号是21308,接着执行

top -H -p 21308
捕获2.PNG

PID为21309,名字为thread_1(上面用prctl设置的)的线程cpu占用率最高。
接着执行

watch -n 1 pstack 21309

输出


捕获3.PNG

问题大概出在nanosleep()接口
进一步验证,执行如下命令

strace -f -p 21309

输出


捕获4.PNG

验证我们的猜想。

上一篇下一篇

猜你喜欢

热点阅读