2

我正在阅读pthread man并看到以下内容:

使用 NPTL,一个进程中的所有线程都放在同一个线程组中;线程组的所有成员共享相同的 PID。

我当前的架构正在运行NPTL 2.17,当我运行htop显示线程时,我看到所有 PID 都是唯一的。但为什么?我期待其中一些(例如chrome)彼此共享相同的PID?

在此处输入图像描述

4

4 回答 4

2

man gettid

gettid() 返回调用者的线程 ID (TID)。在单线程进程中,线程 ID 等于进程 ID(PID,由 getpid(2) 返回)。 在多线程进程中,所有线程都有相同的 PID,但每个线程都有唯一的 TID。 有关详细信息,请参阅 clone(2) 中对 CLONE_THREAD 的讨论。

htop显示的是,TID不是PIDH您可以使用键打开/关闭线程的显示。

您还可以启用PPID列,htop该列显示线程的主线程的 PID / TID。

于 2019-09-04T15:18:45.057 回答
1

Linux 内核确实有 POSIX pids(可在 中探索/proc/*)的概念,但它在内核源代码中将它们称为线程组 id,并将其内部线程 id 称为pids(可在 中探索/proc/*/task/*)。

我相信这植根于 Linux 最初将线程视为“只是进程”,碰巧彼此共享地址空间和一堆其他东西。

您的用户工具可能会传播这个可能令人困惑的 Linux 内核术语。

于 2019-09-04T15:38:29.003 回答
1

谷歌的Chromium 文档(在这些概念方面可能与 Chrome 类似)声明它们使用“多进程架构”。您从 pthread 的手册页中引用的内容指出,单个进程中的所有线程都放在同一个 PID 下,这不适用于 Chrome 的架构。

于 2019-09-04T15:23:45.403 回答
1

因为内核级线程只不过是具有(几乎)相同地址空间的进程。

linux内核开发通过将进程重命名为“threads”,将“pid”-s重命名为“tid”-s,将旧进程重命名为“thread groups”,从而“解决了”这个问题。

然而,可悲的事实是,如果您在 Linux ( clone()) 上创建线程,它将创建一个进程 - 仅使用(几乎)相同的内存段。

这意味着 1:1 线程模型。这意味着所有线程实际上都是内核级线程,这意味着它们本质上是同一地址空间中的进程。

其他一些选择是:

  • 1:M螺纹型号。这意味着内核不知道线程,用户空间库的任务是进行“进程内多任务处理”以看起来像是多线程的。
  • N:M 螺纹模型。这是最好的,不幸的是,有些意见仍然支持 1:1。这意味着我们同时拥有用户级和内核级线程,并且一些优化算法决定运行什么以及在哪里运行。

曾经 Linux 有一个 N:M 模型 (ngpt),但它在另一个后备中被删除。Linux 内核调用本质上是同步的(阻塞)。结果即使是用户空间同步也需要一些内核合作。没有人愿意这样做。

也是这样。

ps 要创建一个性能良好的应用程序,您实际上应该避免一次创建大量线程。您需要使用具有经过深思熟虑的锁定协议的线程池。如果你不最小化线程创建/加入的使用,你的应用程序将会很慢而且效率低下,不管它是否是 N:M 都没有关系。

于 2019-09-04T16:06:14.103 回答