【问题标题】:How does the kernel separate threads from processes内核如何将线程与进程分离
【发布时间】:2015-06-15 07:47:09
【问题描述】:

假设我有一个像 Firefox 这样的浏览器进程,它的 pid = 123。Firefox 有 5 个打开的选项卡,每个选项卡都在单独的线程中运行,所以它总共有 5 个线程。

  1. 所以我想深入了解一下,内核如何将进程分离到线程中执行struct task_struct或thread_info中。

  2. like struct task_struct 是任务列表的任务描述符。 struct task_struct 在哪里包含对这五个线程的引用或链接。

  3. 像Firefox这样的进程的struct thread_struct是否包含对所有5个线程的引用

    或

    每个线程都被视为 Linux 内核中的一个进程。

【问题讨论】:

  • task_struct 包含有关进程的体系结构无关信息。 thread_info 包含体系结构相关信息和内核堆栈。 task_struct 有一个指向 thread_info 的指针,也可以从 thead_info 访问 task_struct。在 linux 中,进程和线程基本上都是 task_structs 的风格。

标签: linux multithreading linux-kernel


【解决方案1】:

与 Windows 不同,Linux 在内核中没有“线程”的实现。内核为我们提供了有时被称为“轻量级进程”的东西,它是“进程”和“线程”概念的概括,可用于实现其中任何一个。

当您阅读内核代码并一方面看到thread_struct 和另一方面pid(进程ID)之类的东西时,可能会感到困惑。实际上,两者都是一回事。不要被术语混淆。

每个轻量级进程都有一个完全不同的thread_info 和task_struct(嵌入了thread_struct)。您似乎认为一个轻量级进程的task_struct 应该具有指向同一(用户空间)“进程”中其他(用户空间)“线程”的task_structs 的指针。不是这种情况。在内核内部,每个“线程”都是一个独立的进程,调度程序分别处理每个进程。

Linux 有一个名为clone 的系统调用,用于创建新的轻量级进程。当您调用clone 时,您必须提供各种标志来指示新进程和现有进程之间将共享什么。他们可以共享他们的地址空间,也可以各自拥有不同的地址空间。他们可以共享打开的文件,也可以各自拥有自己的打开文件列表。他们可以共享自己的信号处理程序,也可以各自拥有自己的信号处理程序。它们可以在同一个“线程组”中,也可以在不同的线程组中。等等……

虽然“线程”和“进程”在 Linux 中是相同的东西,但您可以通过使用 clone 创建不共享它们的进程来实现我们通常认为的“进程”地址空间、打开的文件、信号处理程序等。

您还可以通过使用clone 来实现我们通常认为的“线程”来创建共享其地址空间、打开文件、信号处理程序等的进程。

如果你查看task_struct的定义,你会发现它有指向其他结构体的指针,例如mm_struct(地址空间)、files_struct(打开文件)、sighand_struct(信号处理程序)、等等。当您clone 一个新的“进程”时,所有这些结构都将被复制。当您clone 一个新的“线程”时,这些结构将在新旧task_structs 之间共享——它们都将指向同一个mm_struct,同一个files_struct , 等等。无论哪种方式,您都只是向clone 提供不同的标志来告诉它要复制什么以及要分享什么。

我刚刚在上面提到了“线程组”,所以您可能对此感到疑惑。简而言之,“进程”中的每个“线程”都有自己的 PID,但它们都共享相同的 TGID(线程组 ID)。 TGID 都等于第一个程序线程的 PID。用户空间“PID”,如ps 或/proc 中所示,实际上是内核中的“TGID”。当然,clone 有一个标志来确定一个新的轻量级进程是否会有一个新的 TGID(从而将其放入一个新的“线程组”中)。

UNIX 进程也有“父”和“子”。 Linux task_struct 中有实现父子关系的指针。而且,您可能已经猜到了,clone 有一个标志来确定新轻量级进程的父进程将是什么。它可以是调用clone 的进程,也可以是调用clone 的进程的父。你能弄清楚创建“进程”时使用哪个,创建“线程”时使用哪个?

查看clone 的联机帮助页;这将是非常有教育意义的。还可以在使用 pthread 的程序上尝试 strace 以查看 clone 正在使用中。

(很多都是凭记忆写的;其他人可以根据需要随时进行更正)

【讨论】:

  • 很棒的亚历克斯!这回答了我一口气提出的几个问题:)
猜你喜欢
  • 2016-07-12
  • 2011-02-02
  • 2014-02-17
  • 2015-04-14
  • 2012-05-05
  • 2013-07-15
  • 1970-01-01
  • 2022-10-07
  • 1970-01-01
相关资源
最近更新 更多