Task_struct 用于保存内核进程的必要信息。由于这种结构,内核可以暂停一个进程,并在一段时间后继续执行它。但我的问题是:这个 task_struct 存储在内存中的什么位置(我读过内核堆栈,是在虚拟地址空间的内核空间中的那个吗?)?内核在暂停进程后在哪里保存指向该结构和该结构的指针?
如果您对所描述的资源提供一些参考,我将不胜感激。
PS。我忘了说这个问题是关于 Linux 内核的。
Linux 内核通过 kmem_cache 工具分配一个 task_struct。例如在 fork.c 中有一段代码负责分配一个任务结构:
#define alloc_task_struct_node(node) \
kmem_cache_alloc_node(task_struct_cachep, GFP_KERNEL, node)
static struct kmem_cache *task_struct_cachep;
存储指向当前线程的指针的位置取决于体系结构。例如,这就是 x86 (arch/x86/include/asm/current.h) 的工作方式:
static __always_inline struct task_struct *get_current(void)
{
return percpu_read_stable(current_task);
}
在 PowerPC (arch/powerpc/include/asm/current.h) 中:
static inline struct task_struct *get_current(void)
{
struct task_struct *task;
__asm__ __volatile__("ld %0,%1(13)"
: "=r" (task)
: "i" (offsetof(struct paca_struct, __current)));
return task;
}
您可以使用Elixir 交叉参考来轻松探索内核源代码。
task_struct 是在平板分配器的帮助下分配的。内核中的每个任务都有 8kb 或 4kb 的内核堆栈,它们永远不会增加或减少。
如果我们具体讨论 0x86 架构,那么在任务内核堆栈的末尾,我们有 thread_info 结构,它本质上存储/指向 task_struct 指针。task_struct 具有内核堆栈指针,可以减少 8kb 以获得线程信息结构。
从虚拟内存系统的角度来看,task_struct 是由 Slab 分配器分配的,因此它位于内核空间中。更具体地说,slab 内存可以直接映射到缓存中。
处理线程和进程上下文的内核结构依赖于操作系统。通常,它们将从非分页池中分配,用于管理它们的指针集合也是如此。