内核如何使用task_struct?

Posted

技术标签:

【中文标题】内核如何使用task_struct?【英文标题】:How does the kernel use task_struct? 【发布时间】:2019-10-25 04:16:36 【问题描述】:

我是一名从事 Linux 进程研究的学生,我需要了解更多关于它们的信息才能继续我的实验。在网上阅读几本书和一些东西时,我遇到了task_struct,我不确定我是否完全理解,并希望确认/纠正我现有的想法。

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

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

【问题讨论】:

你可能会发现这个FAQ about 'current' macro很有用。 【参考方案1】:

是的,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

【讨论】:

您能否举一个完整的程序示例来说明如何使用它?我试图在我的模块中实现它,但它给了我很多错误。【参考方案2】:

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

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

要获得thread_info的地址/指针,不同的架构有不同的解决方案,但在x86上看起来像这样:

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

movl $0xFFFFE000, %eax
andl %esp, %eax

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

为了得到它,有一个 current 宏,看起来像这样:

#define current (current_thread_info()->task)

它给你指针(地址)task_struct

【讨论】:

以上是关于内核如何使用task_struct?的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 linux 最新内核中的“thread_info”访问“task_struct”?

了解Linux内核如何管理一个进程的内存

Linux内核第六节 20135332武西垚

Linux内核是如何创建一个新进程的?

20169217 《Linux内核原理与分析》 第八周作业

Linux(内核剖析):04---进程之struct task_struct进程描述符任务结构介绍