/proc/{pid}下记录了每个进程运行时的所有关键信息,那这些信息是谁来生成的呢,答案是Linux内核。
Linux内核在执行你写的程序时,将所有关键信息写到了/proc/{pid}下,因此你可以通过查看这个目录下的信息来或者进程的运行时行为,这对于那些好奇内核是如何运行程序的同学是非常重要的。
你可以把这个目录下的信息理解为Linux内核在执行你写的程序时所打印的Log。通过该Log你就可以知道进程开启了多少线程了。
知道了进程号再去查找对应的线程的简单方式有如下两个:
(1)ps -p {pid} -T 可以得到该进程里面运行的各线程的id(表现出来是spid)、对应的线程名称(不超过16字符)、运行时间等;
(2)/proc/{pid}/status |grep Threads 只能显示线程的个数。
以如下代码为例,我们不断使用上述2种方式获取进程内的线程情况。
#include <pthread.h>
#include <unistd.h>
void* func(void* arg) {
sleep(10000);
}
int main()
{
pthread_t id;
for (int i=0;i<10;i++) {
pthread_create(&id,NULL, func,NULL);
sleep(10);
}
return 0;
}
结果如下:
ok@u20:~/test/threadTest$ ./a.out &
[1] 20141
ok@u20:~/test/threadTest$ ps -p 20141 -T
PID SPID TTY TIME CMD
20141 20141 pts/1 00:00:00 a.out
20141 20142 pts/1 00:00:00 a.out
20141 20145 pts/1 00:00:00 a.out
20141 20148 pts/1 00:00:00 a.out
20141 20150 pts/1 00:00:00 a.out
ok@u20:~/test/threadTest$ ps -p 20141 -T
PID SPID TTY TIME CMD
20141 20141 pts/1 00:00:00 a.out
20141 20142 pts/1 00:00:00 a.out
20141 20145 pts/1 00:00:00 a.out
20141 20148 pts/1 00:00:00 a.out
20141 20150 pts/1 00:00:00 a.out
20141 20152 pts/1 00:00:00 a.out
ok@u20:~/test/threadTest$ ps -p 20141 -T
PID SPID TTY TIME CMD
20141 20141 pts/1 00:00:00 a.out
20141 20142 pts/1 00:00:00 a.out
20141 20145 pts/1 00:00:00 a.out
20141 20148 pts/1 00:00:00 a.out
20141 20150 pts/1 00:00:00 a.out
20141 20152 pts/1 00:00:00 a.out
ok@u20:~/test/threadTest$ ps -p 20141 -T
PID SPID TTY TIME CMD
20141 20141 pts/1 00:00:00 a.out
20141 20142 pts/1 00:00:00 a.out
20141 20145 pts/1 00:00:00 a.out
20141 20148 pts/1 00:00:00 a.out
20141 20150 pts/1 00:00:00 a.out
20141 20152 pts/1 00:00:00 a.out
20141 20157 pts/1 00:00:00 a.out
ok@u20:~/test/threadTest$ ps -p 20141 -T
PID SPID TTY TIME CMD
20141 20141 pts/1 00:00:00 a.out
20141 20142 pts/1 00:00:00 a.out
20141 20145 pts/1 00:00:00 a.out
20141 20148 pts/1 00:00:00 a.out
20141 20150 pts/1 00:00:00 a.out
20141 20152 pts/1 00:00:00 a.out
20141 20157 pts/1 00:00:00 a.out
20141 20165 pts/1 00:00:00 a.out
ok@u20:~/test/threadTest$ ps -p 20141 -T
PID SPID TTY TIME CMD
[1]+ 已完成 ./a.out
ok@u20:~/test/threadTest$
ok@u20:~/test/threadTest$ cat /proc/20141/status |grep Thread
Threads: 2
ok@u20:~/test/threadTest$ cat /proc/20141/status |grep Thread
Threads: 3
ok@u20:~/test/threadTest$ cat /proc/20141/status |grep Thread
Threads: 6
ok@u20:~/test/threadTest$ cat /proc/20141/status |grep Thread
Threads: 7
ok@u20:~/test/threadTest$ cat /proc/20141/status |grep Thread
Threads: 8
ok@u20:~/test/threadTest$ cat /proc/20141/status |grep Thread
cat: /proc/20141/status: 没有那个文件或目录
ok@u20:~/test/threadTest$
这两者是一致的。
重新运行一下程序后(进程号变成20225),打印status记录的内容如下(当时有3个线程):
ok@u20:~/test/threadTest$ cat /proc/20225/status
Name: a.out
Umask: 0002
State: S (sleeping)
Tgid: 20225
Ngid: 0
Pid: 20225
PPid: 7988
TracerPid: 0
Uid: 1000 1000 1000 1000
Gid: 1000 1000 1000 1000
FDSize: 256
Groups: 4 24 27 30 44 46 120 131 132 1000
NStgid: 20225
NSpid: 20225
NSpgid: 20225
NSsid: 7988
VmPeak: 19040 kB
VmSize: 19040 kB
VmLck: 0 kB
VmPin: 0 kB
VmHWM: 552 kB
VmRSS: 552 kB
RssAnon: 80 kB
RssFile: 472 kB
RssShmem: 0 kB
VmData: 16592 kB
VmStk: 132 kB
VmExe: 4 kB
VmLib: 1720 kB
VmPTE: 44 kB
VmSwap: 0 kB
HugetlbPages: 0 kB
CoreDumping: 0
THP_enabled: 1
Threads: 3
SigQ: 0/15275
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000000
SigCgt: 0000000180000000
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 000001ffffffffff
CapAmb: 0000000000000000
NoNewPrivs: 0
Seccomp: 0
Seccomp_filters: 0
Speculation_Store_Bypass: vulnerable
SpeculationIndirectBranch: always enabled
Cpus_allowed: ffffffff,ffffffff,ffffffff,ffffffff
Cpus_allowed_list: 0-127
Mems_allowed: 00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000001
Mems_allowed_list: 0
voluntary_ctxt_switches: 2
nonvoluntary_ctxt_switches: 0
ok@u20:~/test/threadTest$