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

SPS*_*PSN 91 multithreading pid linux-kernel

我有一个与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)概念?

pax*_*blo 253

四个线程将具有相同的PID,但仅限于从上方查看时.什么,你(作为一个用户)调用PID是不是有什么内核(从下面看)调用PID.

内核中,每个线程都有自己的ID,称为PID(虽然将它称为TID或线程ID可能更有意义)并且它们也有一个TGID(线程组ID),它是线程的PID这开始了整个过程.

简单地说,当创建新进程时,它显示为一个线程,其中PID和TGID都是相同(新)的数字.

当一个线程启动另一个线程时,该启动的线程获得自己的PID(因此调度程序可以独立地调度它),但它从原始线程继承TGID.

这样,内核可以愉快地调度线程,而不管它们属于哪个进程,同时向您报告进程(线程组ID).

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

                      USER VIEW
 <-- PID 43 --> <----------------- PID 42 ----------------->
                     +---------+
                     | process |
                    _| pid=42  |_
                  _/ | tgid=42 | \_ (new thread) _
       _ (fork) _/   +---------+                  \
      /                                        +---------+
+---------+                                    | process |
| process |                                    | pid=44  |
| pid=43  |                                    | tgid=42 |
| tgid=43 |                                    +---------+
+---------+
 <-- PID 43 --> <--------- PID 42 --------> <--- PID 44 --->
                     KERNEL VIEW
Run Code Online (Sandbox Code Playgroud)

您可以看到启动一个新进程(在左侧)为您提供了一个新的PID 一个新的TGID(都设置为相同的值),而启动一个新的线程(在右侧)为您提供了一个新的PID,同时保持相同TGID作为启动它的线程.


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

  • 仅供参考,`getpid()`返回tgid:`asmlinkage long sys_getpid(void){return current-> tgid;}`,如[www.makelinux.com/](http://www.makelinux.com/books)所示/ LKD2/ch05lev1sec2) (17认同)
  • @Duke - 哇,这就是为什么我找不到`gettgid(2)`函数.并且`getpid()`不会返回TID(线程的"PID"),并且`gettid(2)`进来.这样我可以判断,如果我们在主线程中. (4认同)
  • 这引出了另一个有趣的观点:因此,如果线程和进程在内核中同等处理(除了tgid),多线程进程最终会比单线程进程获得更多的CPU时间,前提是它们都具有相同的优先级并且没有任何线程因任何原因而停止(例如等待互斥锁). (2认同)

Jes*_*mos 5

线程使用 PID 和 TGID(线程组 ID)来标识。他们还知道哪个线程是哪个线程的父线程,因此本质上进程与其启动的任何线程共享其 PID。线程 ID 通常由线程库本身管理(例如 pthread 等)。如果 4 个线程启动,它们应该具有相同的 PID。内核本身将处理线程调度等,但库是管理线程的库(它们是否可以运行取决于您对线程加入和等待方法的使用)。

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