我正在阅读pthread man并看到以下内容:
使用 NPTL,一个进程中的所有线程都放在同一个线程组中;线程组的所有成员共享相同的 PID。
我当前的架构正在运行NPTL 2.17
,当我运行htop
显示线程时,我看到所有 PID 都是唯一的。但为什么?我期待其中一些(例如chrome)彼此共享相同的PID?
我正在阅读pthread man并看到以下内容:
使用 NPTL,一个进程中的所有线程都放在同一个线程组中;线程组的所有成员共享相同的 PID。
我当前的架构正在运行NPTL 2.17
,当我运行htop
显示线程时,我看到所有 PID 都是唯一的。但为什么?我期待其中一些(例如chrome)彼此共享相同的PID?
gettid() 返回调用者的线程 ID (TID)。在单线程进程中,线程 ID 等于进程 ID(PID,由 getpid(2) 返回)。 在多线程进程中,所有线程都有相同的 PID,但每个线程都有唯一的 TID。 有关详细信息,请参阅 clone(2) 中对 CLONE_THREAD 的讨论。
htop
显示的是,TID
不是PID
。H
您可以使用键打开/关闭线程的显示。
您还可以启用PPID
列,htop
该列显示线程的主线程的 PID / TID。
Linux 内核确实有 POSIX pids(可在 中探索/proc/*
)的概念,但它在内核源代码中将它们称为线程组 id,并将其内部线程 id 称为pid
s(可在 中探索/proc/*/task/*
)。
我相信这植根于 Linux 最初将线程视为“只是进程”,碰巧彼此共享地址空间和一堆其他东西。
您的用户工具可能会传播这个可能令人困惑的 Linux 内核术语。
谷歌的Chromium 文档(在这些概念方面可能与 Chrome 类似)声明它们使用“多进程架构”。您从 pthread 的手册页中引用的内容指出,单个进程中的所有线程都放在同一个 PID 下,这不适用于 Chrome 的架构。
因为内核级线程只不过是具有(几乎)相同地址空间的进程。
linux内核开发通过将进程重命名为“threads”,将“pid”-s重命名为“tid”-s,将旧进程重命名为“thread groups”,从而“解决了”这个问题。
然而,可悲的事实是,如果您在 Linux ( clone()
) 上创建线程,它将创建一个进程 - 仅使用(几乎)相同的内存段。
这意味着 1:1 线程模型。这意味着所有线程实际上都是内核级线程,这意味着它们本质上是同一地址空间中的进程。
其他一些选择是:
曾经 Linux 有一个 N:M 模型 (ngpt),但它在另一个后备中被删除。Linux 内核调用本质上是同步的(阻塞)。结果即使是用户空间同步也需要一些内核合作。没有人愿意这样做。
也是这样。
ps 要创建一个性能良好的应用程序,您实际上应该避免一次创建大量线程。您需要使用具有经过深思熟虑的锁定协议的线程池。如果你不最小化线程创建/加入的使用,你的应用程序将会很慢而且效率低下,不管它是否是 N:M 都没有关系。