6

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

谢谢

4

2 回答 2

6

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

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

于 2012-10-17T21:22:04.873 回答
4

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

引用此讨论

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

NPTL 上的维基百科链接

NPTL 自版本 3 以来一直是 Red Hat Enterprise 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

以下程序在 Linux 内核 2.6.18 下为 main 和 thread 输出相同的 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);
}

输出是:

main: pid = 13246, self = 46912496175248
thread: pid = 13246, self = 1084229952
于 2012-10-17T21:22:50.310 回答