内核如何使用task_struct?

How does the kernel use task_struct?

我是一名研究涉及 Linux 过程的学生,我需要更多地了解它们才能继续我的实验。在网上阅读了几本书和一些东西时,我遇到了 task_struct,我不确定我是否完全理解了,并且希望 confirmation/correction 符合我现有的想法。

据我所知,task_struct 是充当进程描述符的 C 结构,包含内核可能需要了解的有关进程的所有信息。在进程内核堆栈的末尾有另一个结构 thread_info,它有一个指向进程 task_struct.

的指针

另一个问题:如何访问进程的task_struct?是否有计算找到它的位置 thread_info?内核中有macro/function吗?

是的,task_struct 结构包含有关进程的所有信息。您可以使用 current 宏获取指向描述当前进程的结构的指针,如下所示:

struct task_struct *p = current;

如果要获取描述给定 pid 进程的结构,可以使用 find_task_by_vpid 函数,如下所示:

read_lock(&tasklist_lock);
p = find_task_by_vpid(pid);
if (p) get_task_struct(p);
read_unlock(&tasklist_lock);
if (p == NULL) {
    // Task not found.
}

// Later, once you're finished with the task, execute:
put_task_struct(p);

最后,如果要遍历所有进程,可以使用for_each_process如下:

read_lock(&tasklist_lock);
for_each_process(p) {
    // p is a pointer to a task_struct instance.
}
read_unlock(&tasklist_lock);

如果您希望独占访问任务列表以便能够更改结构中的一个或多个字段,则必须使用 write_lock_irqsave 而不是 read_lock

让我试着回答第二个问题。

在每个进程内核堆栈的顶部有一个结构thread_info.

获取地址of/pointer到thread_info,不同的架构有不同的解决方案,但在x86上它看起来像这样:

要获取指向 thread_info 的指针,只需屏蔽堆栈指针值的 13 位:

movl [=10=]xFFFFE000, %eax
andl %esp, %eax

现在我们有指针了,这个结构有task_struct结构的指针。

要获取它,有一个 current 宏,看起来像这样:

#define current (current_thread_info()->task)

它给你指针(地址)task_struct