Linux内核:线程与进程 – task_struct vs thread_info

我读过Linux不支持线程或轻量级进程的概念,并认为内核线程就像任何其他进程一样。 但是这个原则在代码里面并不是很准确。 我们看到task_struct保存一个进程的状态信息(如果错误,请纠正我)以及thread_info追加到进程内核堆栈的底部。

现在的问题是,为什么代码支持通过thread_info单独线程的概念,当linux应该像任何其他进程解释线程?

请让我知道我在这里失踪 – 我是一个Linux内核开发新手。

Linux中的线程被视为恰好共享一些资源的进程。 每个线程都有自己的thread_info (如你所说的在堆栈底部)和它自己的task_struct 。 我可以想到为什么他们作为单独的结构维护的两个原因。

  1. thread_info是依赖于体系结构的。 task_struct是通用的。
  2. thread_info将该进程的内核堆栈大小裁减,因此应该保持较小。 thread_info被放置在堆栈的底部作为一个微优化,使得可以通过堆栈大小向下舍入来计算其当前堆栈指针的地址,从而保存一个CPU寄存器。

正如Peter所说的,thread_info是一个特定的体系结构,包含必要的信息,如寄存器,pc,fp等

这个信息是在上下文切换期间保存/恢复流程执行所必需的。

http://lxr.free-electrons.com/source/arch/arm/include/asm/thread_info.h#L33

task_struct – > thread_info – > struct cpu_context_save cpu_context

较旧的方法:在较早的内核中,在2.6之前,进程描述符是静态分配的,因此可以从该结构的特定偏移量读取值。

新方法:但在2.6及更高版本中,您可以使用slab分配器动态分配进程描述符。 因此,旧的方法不再有效。 因此引入了Thread_info

在“Linux内核开发”一书中明确提到,第3章:

task_struct结构通过slab分配器进行分配,以提供对象重用和缓存着色(请参见第11章“内存管理”)。 在2.6内核系列之前,struct task_struct存储在每个进程的内核堆栈的末尾。 这允许具有很少寄存器的体系结构(如x86)通过堆栈指针计算进程描述符的位置,而不使用额外的寄存器来存储位置。 现在,通过slab分配器动态创建进程描述符,创建了一个新的结构struct thread_info,它再次位于堆栈底部(对于堆栈向下扩展)和堆栈顶部(对于堆栈长大)[4]。 见图3.2。 新的结构也可以很容易地计算在汇编代码中使用的值的偏移量。

task_struct是一个大型的数据结构。 因此,存储大型结构的任务是非常困难的。 所以内核引入了thread_info概念,它比task_struct要细得多,只是指向task_struct结构。

资源