是否存在 PID 最终不是唯一的情况?它是识别进程(或线程)的最佳方法吗?我读到以前版本的 Linux 有不同的方法
谢谢
是否存在 PID 最终不是唯一的情况?它是识别进程(或线程)的最佳方法吗?我读到以前版本的 Linux 有不同的方法
谢谢
PID 可以取大约 32k 值(sysctl kernel.pid_max
可以更改它),因此它们被足够快地重用。pid + 开始时间可能会更好。systemd 在 cgroupfs 中附加每个进程的扩展属性信息(procfs 也可以)以避免 pid->attr 映射的歧义。
线程和进程共享相同的命名空间(您可以在 中看到它/proc/<pid>/task/<taskid>
),其中<pid>
=<taskid>
表示进程的初始线程。Pid 命名空间限制了可见 pid 的列表,但它们不会引入任何重叠;pid 和任务 ID 在其所有者运行时保持唯一。
如果您在谈论getpid()
系统调用,那么是的,每个进程的 PID 都是唯一的。除外,也就是说,如果您在旧版本的 Linux 内核上使用线程。然后每个线程可能有自己的进程ID。
引用此讨论:
内核 2.4.20 使用NPTL(本地 posix 线程库),这是 RH9 附带的内核。RH8 使用没有实现 NPTL 的内核 2.4.18(这意味着每个线程都有自己的 PID,因此在 /proc 中很好地描述了它的状态)。NPTL 是 POSIX 线程的“真正”实现,这意味着线程共享更多,包括 PID。出于几个原因,它是运行线程的更有效方式,但是,我不知道有什么简单的技巧可以调试这些线程。您如何知道您的线程何时处于睡眠状态与等待信号量,或者哪些线程在具有大量线程的进程中死亡,等等。
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