pid真的很独特吗

Buf*_*alo 5 linux multithreading kernel pid process

是否存在PID最终不唯一的情况?这是识别进程(或线程)的最佳方法吗?我读到以前的Linux版本有不同的方法

谢谢

Tob*_*obu 5

PID 可以采用大约 32k 个值(sysctl kernel.pid_max可以更改它),因此它们可以足够快地重复使用。pid + 开始时间可能会更好。systemd 将每个进程的信息附加到 cgroupfs 中的扩展属性上(procfs 也可以工作),以避免 pid->attr 映射的歧义。

线程和进程共享相同的命名空间(您可以在 中看到/proc/<pid>/task/<taskid>),其中<pid>=<taskid>代表进程的初始线程。pid 命名空间限制了可见 pid 的列表,但它们不会引入任何重叠;pids 和 task ids 在它们的所有者运行时保持唯一。


Gra*_*ray 5

如果您谈论的是getpid()系统调用,那么是的,每个进程的 PID 都是唯一的。除非您在旧版本的 Linux 内核上使用线程。那么每个线程可能有自己的进程ID。

引用此讨论

内核 2.4.20 使用NPTL(本机 posix 线程库),这是 RH9 附带的内核。RH8 使用不实现 NPTL 的内核 2.4.18(这意味着每个线程都有自己的 PID,因此在 /proc 中可以很好地描述其状态)。NPTL 是 POSIX 线程的“真正”实现,这意味着线程共享更多内容,包括 PID。由于多种原因,它是运行线程的更有效的方式,但是,我不知道调试此类线程的任何简单技巧。您如何知道您的线程何时处于睡眠状态或等待信号量,或者哪些线程在具有大量线程的进程中已死亡,等等。

来自NPTL 上的维基百科链接

NPTL 自版本 3 起成为红帽企业 Linux 的一部分,并自版本 2.6 起成为 Linux 内核的一部分。它现在是 GNU C 库的完全集成的一部分。2

在幕后,甚至 2.6.X 内核也有一个线程虚拟进程。您可以使用以下命令查看线程进程 ID ps auxf

root      2501  0.0  0.3 244448 25576 ?    Ss   Jul03   0:11 /usr/sbin/httpd
apache    2716  0.0  0.5 384776 46696 ?    S    Oct14   0:17  \_ /usr/sbin/httpd
apache    2717  0.0  0.5 382208 44304 ?    S    Oct14   0:11  \_ /usr/sbin/httpd
Run Code Online (Sandbox Code Playgroud)

以下程序在 Linux 内核 2.6.18 下为主线程和线程输出相同的 pid。返回的 self idpthread_self()唯一标识该线程。

#include <pthread.h>
void foo() {
  printf("thread: pid = %d, self = %ld\n", getpid(), pthread_self());
}
main() {
  pthread_t thread;
  printf("main: pid = %d, self = %ld\n", getpid(), pthread_self());
  pthread_create(&thread, 0L, foo, 0L);
  pthread_join(thread, 0L);
}
Run Code Online (Sandbox Code Playgroud)

输出是:

main: pid = 13246, self = 46912496175248
thread: pid = 13246, self = 1084229952
Run Code Online (Sandbox Code Playgroud)