Linux服务器查看进程每个线程的执行任务

在Linux操作系统中,我们可以使用很多种方法来查看一个进程中的多个线程以及每个线程正在执行的任务。

以下是一些常用的方法:

1. 使用ps命令

你可以使用ps命令结合-eLf选项来查看每个线程及其状态。

ps -eLf | grep 进程ID

其中,进程ID是你想要查看的进程的ID。这个命令会列出该进程下的所有线程及其详细信息。

$ ps -eLf | grep 807
root         807       1     807  0    1 1月29 ?       00:00:00 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
root      137466     807  137466  0    1 3月04 ?       00:00:00 sshd: byzoro [priv]
root      137810     807  137810  0    1 3月04 ?       00:00:00 sshd: byzoro [priv]
root      142099     807  142099  0    1 3月04 ?       00:00:00 sshd: byzoro [priv]
root      156998     807  156998  0    1 14:06 ?        00:00:00 sshd: byzoro [priv]
root      158075       2  158075  0    1 15:17 ?        00:00:00 [kworker/7:0]
byzoro    158598  137850  158598  0    1 15:28 pts/1    00:00:00 grep --color=auto 807
ps -eLf
UID          PID    PPID     LWP  C NLWP STIME TTY          TIME CMD
root           1       0       1  0    1 1月29 ?       00:02:03 /sbin/init splash
root           2       0       2  0    1 1月29 ?       00:00:02 [kthreadd]
root           3       2       3  0    1 1月29 ?       00:00:00 [rcu_gp]

输出列表说明:

这些是Linux系统中ps命令的输出,用于显示当前系统中的进程信息。

下面是每个字段的解释:

  1. UID (User ID): 进程的所有者ID。在这个例子中,所有进程都是root用户,这意味着它们是系统进程或由root用户启动的。
  2. PID (Process ID): 进程的唯一标识符。它是系统中每个进程的唯一数字。
  3. PPID (Parent Process ID): 父进程的PID。每个进程通常都有一个父进程,它创建了该进程。在这个例子中,我们可以看到许多进程的父进程是init进程(PID为1),这是系统的第一个进程。
  4. LWP (Light Weight Process): 线程ID。在多线程程序中,每个线程都有一个唯一的LWP。对于非多线程程序,LWP通常与PID相同。
  5. C (CPU Utilization): CPU利用率。这表示进程当前占用的CPU使用率。0表示该进程当前没有使用CPU。
  6. NLWP (Number of Light Weight Processes): 进程中的线程数量。对于单线程进程,这通常是1
  7. STIME (Start Time): 进程的启动时间。
  8. TTY (Controlling Terminal): 进程关联的终端。?表示该进程没有与任何终端关联。
  9. TIME (CPU Time): 进程使用的CPU总时间。这通常包括用户模式和内核模式的CPU时间。
  10. CMD (Command Name/Line): 启动进程的命令名称或命令行。

在这个输出中,你可以看到各种系统进程,如initkthreaddrcu_gp。这些都是Linux内核和初始化系统的一部分,它们在系统启动时自动启动,并在系统运行时持续运行。

2. 使用top命令

top命令是一个实时显示系统中各个进程的资源占用状况的监控工具。你可以通过按H键来显示线程,而不是进程。

top命令运行时,按H,然后按P(按CPU使用率排序)或M(按内存使用率排序)来查看线程的详细信息。

3. 使用htop命令

htoptop的一个增强版,它提供了一个彩色的界面,并支持鼠标操作。在htop中,你可以直接看到每个进程下的线程,并按需要排序和筛选。

首先,你需要安装htop

sudo apt install htop  # 对于Debian/Ubuntu系统  sudo yum install htop  # 对于CentOS/RedHat系统

然后,运行htop并查看进程和线程信息。

$ htop
图片[1]-Linux服务器查看进程每个线程的执行任务-不念博客
htop命令

4. 使用gdb

gdb是一个强大的调试工具,你也可以使用它来查看进程中的线程和它们的堆栈跟踪。

gdb -p 进程ID  (gdb) info threads

这将显示所有线程的列表。你可以使用thread 线程ID来切换到特定的线程,并使用bt命令来查看该线程的堆栈跟踪。

如何使用gdb调试一个多线程的程序:

multithread_example.c

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h> // 用于sleep函数

void *print_message_function(void *ptr) {
    long tid;
    tid = (long)ptr;
    printf("线程 #%ld 正在运行\n", tid);
    sleep(100); // 每个线程等待100秒
    pthread_exit(NULL);
}

int main() {
    pthread_t thread1, thread2;
    const long num_threads = 2;
    int rc;
    long t;

    for(t = 0; t < num_threads; t++) {
        printf("创建线程 %ld\n", t);
        if (t == 0) {
            rc = pthread_create(&thread1, NULL, print_message_function, (void *)t);
        } else {
            rc = pthread_create(&thread2, NULL, print_message_function, (void *)t);
        }
        if (rc) {
            printf("Error:无法创建线程, %d\n", rc);
            exit(-1);
        }
    }

    // 等待线程1和线程2完成
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);

    // 所有线程已经结束,现在主线程可以退出
    pthread_exit(NULL);
}

编译这个程序,确保链接了pthread库:

gcc -o multithread_example multithread_example.c -lpthread

然后,你可以运行这个程序,并使用gdb来附加到它:

$ ./multithread_example &  # 在后台运行程序  
$ sudo gdb -p <进程ID>          # 使用gdb附加到进程
# gdb命令需要root权限

gdb提示符下,你可以使用info threads来查看所有线程的列表,然后使用thread <线程ID>来切换到特定的线程,并使用bt(backtrace)命令来查看该线程的堆栈跟踪。

示例gdb会话如下:

(gdb) info threads  
  Id   Target Id         Frame   
* 1    Thread 0x7ffff7fd6700 (LWP 12345) "multithread_exam" 0x00007ffff7a9c94d in __GI___nanosleep () at ../sysdeps/unix/syscall-template.S:81  
  2    Thread 0x7ffff77d5700 (LWP 12346) "multithread_exam" 0x00007ffff7a9c94d in __GI___nanosleep () at ../sysdeps/unix/syscall-template.S:81  

(gdb) thread 2  
[Switching to thread 2 (Thread 0x7ffff77d5700 (LWP 12346))]  
#0  0x00007ffff7a9c94d in __GI___nanosleep () at ../sysdeps/unix/syscall-template.S:81  
#1  0x00007ffff7a9c884 in sleep () at ../sysdeps/unix/sysv/linux/sleep.c:50  
#2  0x0000555555555114 in print_message_function (ptr=0x555555754f8c) at multithread_example.c:9  
#3  0x00007ffff7b936db in start_thread (arg=0x7ffff77d5700) at pthread_create.c:463  
#4  0x00007ffff78c988f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95  

(gdb) bt  
#0  0x00007ffff7a9c94d in __GI___nanosleep () at ../sysdeps/unix/syscall-template.S:81  
#1  0x00007ffff7a9c884 in sleep () at ../sysdeps/unix/sysv/linux/sleep.c:50  
#2  0x0000555555555114 in print_message_function (ptr=0x55
图片[2]-Linux服务器查看进程每个线程的执行任务-不念博客
后台执行程序
图片[3]-Linux服务器查看进程每个线程的执行任务-不念博客
gdb

5. perf top -p 进程ID

使用perf工具。

perf top -p 进程ID

这将显示按CPU使用率排序的进程和线程列表。你可以看到每个线程当前正在执行的函数。

注意:perf工具可能需要root权限来运行。

图片[4]-Linux服务器查看进程每个线程的执行任务-不念博客
perf工具查看结果
© 版权声明
THE END