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
验证我们的猜想。
网友评论