如果线程共享相同的 PID,如何识别它们?

我有一个关于 Linux 中线程实现的查询。

Linux 没有显式的线程支持。在用户空间中,我们可以使用线程库(如 NPTL)来创建线程。现在如果我们使用 NPTL,它支持1:1映射。

内核将使用 clone()函数来实现线程。

假设我已经创建了4个线程,那么这就意味着:

  • 会有4个 task_struct
  • task_struct内部,将根据克隆 (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND)的参数提供共享资源。

现在我有以下问题:

  1. 这4个线程是否具有相同的 PID? 如果有人可以详细说明,PID 是如何共享的。
  2. 如何识别不同的线程; 是否有一些 TID (线程 ID)概念?
65362 次浏览

使用 PID 和 TGID (线程组 ID)标识线程。它们还知道哪个线程是哪个进程的父线程,因此从本质上讲,进程与它启动的任何线程共享其 PID。线程 ID 通常由线程库本身管理(如 pthread 等)。.).如果启动4个线程,它们应该具有相同的 PID。内核本身将处理线程调度之类的事情,但是库将负责管理线程(它们是否能够运行取决于您对线程连接和等待方法的使用)。

注意: 这是我对内核2.6.36的回忆。我在当前内核版本中的工作是在 I/O 层,所以我不知道那之后是否发生了变化。

这四个线程将具有相同的 PID,但只有当从 以上。查看时,you(作为用户)调用的 PID 不是内核(从下面查看)调用的 PID。

内核,中,每个线程都有自己的 ID,称为 PID,尽管称之为 TID 或线程 ID 可能更有意义,而且它们还有一个 TGID (线程组 ID) ,这是创建进程时创建的第一个线程的 PID。

当创建一个新的 程序时,它显示为一个线程,其中 PID 和 TGID 都是相同的(当前未使用)数字。

When a thread starts another 线, that new thread gets its own PID (so the scheduler can schedule it independently) but it inherits the TGID from the original thread.

通过这种方式,内核可以独立于线程所属的进程而快乐地调度线程,而进程(线程组 ID)则报告给您。

下面的线程层次结构可能有助于 (a):

                         USER VIEW
vvvv vvvv
|
<-- PID 43 -->|<----------------- PID 42 ----------------->
|                           |
|      +---------+          |
|      | process |          |
|     _| pid=42  |_         |
__(fork) _/ | tgid=42 | \_ (new thread) _
/     |      +---------+          |       \
+---------+   |                           |    +---------+
| process |   |                           |    | process |
| pid=43  |   |                           |    | pid=44  |
| tgid=43 |   |                           |    | tgid=42 |
+---------+   |                           |    +---------+
|                           |
<-- PID 43 -->|<--------- PID 42 -------->|<--- PID 44 --->
|                           |
^^^^^^ ^^^^
KERNEL VIEW

您可以看到,启动一个新的 程序(在左侧)将为您提供一个新的 PID 还有和一个新的 TGID (都设置为相同的值)。启动一个新的 线(在右边)将为您提供一个新的 PID,同时维护与启动它的线程相同的 TGID。


(a) 敬畏地颤抖在我令人印象深刻的图形技能: -)

Linux 为 fork()系统调用提供了复制进程的传统功能。Linux 还提供了使用 clone()系统调用创建线程的能力。然而,Linux 并不区分进程和线程。