Linux内核:线程与进程 - task_struct与thread_info

Ace*_*Ace 10 linux multithreading kernel process

我读到Linux不支持线程或轻量级进程的概念,并且它认为内核线程就像任何其他进程一样.但是这个原则在代码中并没有非常准确地反映出来.我们看到task_struct保存了进程的状态信息(如果错误则纠正我),并且还将thread_info附加到进程内核堆栈的底部.

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

请让我知道我在这里缺少什么 - 我是linux内核开发的新手.

Pet*_*ren 14

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

  1. thread_info是建筑依赖的.task_struct是通用的.
  2. thread_info切入该进程的内核堆栈的大小,因此它应该保持很小.thread_info作为微优化放置在堆栈的底部,通过向下舍入保存CPU寄存器的堆栈大小,可以从当前堆栈指针计算其地址.


bro*_*oot 6

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

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

Linux Kernel Development, Chapter 3一书中明确提到:

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


Siv*_*mar 5

正如 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