由一个进程创建的多个线程具有相同的 pid,也就是在这些线程中分别调用 getpid(),得到的结果是一样的。
这里的 pid 其实是 task struct(进程描述符结构体)中的 tgid,它是线程的 group ID,也是主线程(它创建了子线程)的 PID。
而 task struct 中的 pid 其实是线程的 ID, 也可以叫作 tid(thread ID),对于多线程而言,这些 tid 是不同的。
借用 stackoverflow 上的一个回答来解释这里面的逻辑,下面这张图形象的描述了多进程和多线程中 pid 与 tgid 的关系。
最后引用内核中 kernel/sys.c 文件里关于 getpid() 系统调用的注释来说明这个问题:
/**
* sys_getpid - return the thread group id of the current process
*
* Note, despite the name, this returns the tgid not the pid. The tgid and
* the pid are identical unless CLONE_THREAD was specified on clone() in
* which case the tgid is the same in all threads of the same group.
*
* This is SMP safe as current->tgid does not change.
*/
SYSCALL_DEFINE0(getpid)
{
return task_tgid_vnr(current);
}
参考资料:
1、https://stackoverflow.com/questions/9305992/if-threads-share-the-same-pid-how-can-they-be-identified