当我运行 top 然后按 H 或运行 ps -Hef 时,我发现区分线程和进程相当令人困惑。
我知道它们具有相同的属性,这使得它们相似,但想知道输出中是否有任何内容可用于识别什么是进程,什么是线程?
对我来说它们看起来都像是常规过程,因此很难区分。
答案1
我知道这个问题有点老了,但只是为任何看到这个问题的人提供参考。
默认情况下,ps 不显示线程,但您可以使用-T标记以查看它们。这与-飞使用长格式打印输出的选项将为您提供所需的信息:
ps -flye -T
要区分进程和线程,可以使用 PID 和 SPID 字段。所有线程共享相同的 PID,但具有唯一的 SPID。当 PID==SPID 时,即为父进程。
出于调试目的,我发现查看特定进程的线程非常有用:
$ ps -fly -T -p 193471
S UID PID SPID PPID C PRI NI RSS SZ WCHAN STIME TTY TIME CMD
S root 193471 193471 193466 0 80 0 902460 871117 poll_s 10:46 ? 00:00:17 /usr/bin/python36 xyzzy
S root 193471 193665 193466 4 80 0 902460 871117 futex_ 10:46 ? 00:01:22 /usr/bin/python36 xyzzy
S root 193471 193667 193466 4 80 0 902460 871117 futex_ 10:46 ? 00:01:32 /usr/bin/python36 xyzzy
S root 193471 193669 193466 4 80 0 902460 871117 futex_ 10:46 ? 00:01:26 /usr/bin/python36 xyzzy
S root 193471 193672 193466 4 80 0 902460 871117 futex_ 10:46 ? 00:01:23 /usr/bin/python36 xyzzy
S root 193471 193676 193466 4 80 0 902460 871117 poll_s 10:46 ? 00:01:33 /usr/bin/python36 xyzzy
答案2
我认为你应该关注的是“执行上下文”。每个进程(或任务)都有自己的地址空间。将线程视为使用相同地址空间的进程子集。ps 和 top 不会显示这一点,但可以四处查看/proc/<pid>status
。/proc/<pid>map
也可以尝试 strace 和 gdb 来查看程序正在做什么。这是一个使用 pthread_create 的简单 c 程序的 gdb 输出。
# gdb mythread
;...]
Reading symbols from /root/mythread...(no debugging symbols found)...done.
(gdb) break main
Breakpoint 1 at 0x40080f
(gdb) break hello_world
Breakpoint 2 at 0x400761
(gdb) r
Starting program: /root/mythread
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Breakpoint 1, 0x000000000040080f in main ()
(gdb) c
Continuing.
The main process id is 12887
[New Thread 0x7ffff77f1700 (LWP 12891)]
[Switching to Thread 0x7ffff77f1700 (LWP 12891)]
Breakpoint 2, 0x0000000000400761 in hello_world ()
(gdb) c
Continuing.
[New Thread 0x7ffff6ff0700 (LWP 12892)]
[Switching to Thread 0x7ffff6ff0700 (LWP 12892)]
Breakpoint 2, 0x0000000000400761 in hello_world ()
用户信息过程映射
(gdb) info proc mappings
process 12896
Mapped address spaces:
Start Addr End Addr Size Offset objfile
0x400000 0x401000 0x1000 0x0 /root/mythread
0x600000 0x601000 0x1000 0x0 /root/mythread
0x601000 0x602000 0x1000 0x1000 /root/mythread
0x7ffff77f2000 0x7ffff79b5000 0x1c3000 0x0 /usr/lib64/libc-2.17.so
0x7ffff79b5000 0x7ffff7bb4000 0x1ff000 0x1c3000 /usr/lib64/libc-2.17.so
0x7ffff7bb4000 0x7ffff7bb8000 0x4000 0x1c2000 /usr/lib64/libc-2.17.so
0x7ffff7bb8000 0x7ffff7bba000 0x2000 0x1c6000 /usr/lib64/libc-2.17.so
0x7ffff7bba000 0x7ffff7bbf000 0x5000 0x0
0x7ffff7bbf000 0x7ffff7bd6000 0x17000 0x0 /usr/lib64/libpthread-2.17.so
0x7ffff7bd6000 0x7ffff7dd5000 0x1ff000 0x17000 /usr/lib64/libpthread-2.17.so
0x7ffff7dd5000 0x7ffff7dd6000 0x1000 0x16000 /usr/lib64/libpthread-2.17.so
0x7ffff7dd6000 0x7ffff7dd7000 0x1000 0x17000 /usr/lib64/libpthread-2.17.so
0x7ffff7dd7000 0x7ffff7ddb000 0x4000 0x0
0x7ffff7ddb000 0x7ffff7dfd000 0x22000 0x0 /usr/lib64/ld-2.17.so
0x7ffff7fed000 0x7ffff7ff0000 0x3000 0x0
0x7ffff7ff9000 0x7ffff7ffa000 0x1000 0x0
0x7ffff7ffa000 0x7ffff7ffc000 0x2000 0x0 [vdso]
0x7ffff7ffc000 0x7ffff7ffd000 0x1000 0x21000 /usr/lib64/ld-2.17.so
0x7ffff7ffd000 0x7ffff7ffe000 0x1000 0x22000 /usr/lib64/ld-2.17.so
0x7ffff7ffe000 0x7ffff7fff000 0x1000 0x0
0x7ffffffde000 0x7ffffffff000 0x21000 0x0 [stack]
0xffffffffff600000 0xffffffffff601000 0x1000 0x0 [vsyscall]