什么是内核线程?

Posted

技术标签:

【中文标题】什么是内核线程?【英文标题】:What is a Kernel thread? 【发布时间】:2012-03-17 20:56:28 【问题描述】:

我刚开始编写设备驱动程序和线程新手,浏览了许多文档以了解线程。我还有一些疑问。

    。 它与用户线程有何不同?。 这两个线程之间是什么关系?。 如何实现内核线程?。 在哪里可以看到实现的输出?

谁能帮助我? 谢谢。

【问题讨论】:

你读过我猜的这个吗? en.wikipedia.org/wiki/Thread_(computing)这至少应该回答你的一些问题。 在类似的上下文中还有this previous answer。 【参考方案1】:
    内核线程是没有用户空间组件的task_struct。 除了缺少用户空间之外,它还有不同的祖先(kthreadd 内核线程而不是 init 进程)并且是由仅内核 API 而不是来自 fork/exec 系统调用的 clone 序列创建的。 两个内核线程有kthreadd 作为父级。除此之外,内核线程享有与用户空间进程相同的“独立性”。 使用kthread.h header 中的kthread_run 函数/宏 您很可能必须编写一个内核模块才能调用此函数,因此您应该看看Linux Device Drivers 如果您指的是实现的文本输出(通过printk 调用),您可以使用dmesg 命令在内核日志中看到此输出。

【讨论】:

【参考方案2】:

用户线程和堆栈:

每个线程都有自己的堆栈,因此它可以使用自己的局部变量、线程共享的全局变量,这些变量是 linux 可执行文件的 .data 或 .bss 部分的一部分。 由于线程共享全局变量,即当我们想要访问/修改多线程应用程序中的全局变量时,我们使用像互斥锁这样的同步机制。局部变量是线程独立堆栈的一部分,因此不需要任何同步。

内核线程 内核线程源于在进程上下文中运行内核代码的需要。内核线程是工作队列机制的基础。从本质上讲,线程内核是一个只运行在内核态的线程,没有用户地址空间或其他用户属性。

要创建线程内核,请使用 kthread_create():

#include <linux/kthread.h>

structure task_struct *kthread_create(int (*threadfn)(void *data),
                                      void *data, const char namefmt[], ...);

内核线程和堆栈: 内核线程用于为内核执行后处理任务,例如 pdf 刷新线程、workq 线程等。 内核线程基本上是没有地址空间的新进程(可以使用带有所需标志的 clone() 调用创建),这意味着它们不能切换到用户空间。内核线程可以像正常进程一样被调度和抢占。

内核线程有自己的堆栈,用于管理本地信息。

关于内核堆栈的更多信息:- https://www.kernel.org/doc/Documentation/x86/kernel-stacks

【讨论】:

【参考方案3】:

内核线程是只在内核模式下运行的内核任务;它通常不是由fork()clone() 系统调用创建的。一个例子是kworkerkswapd

如果您不知道内核线程是什么,您可能不应该实现它们。

Google 提供了许多关于内核线程的页面,例如Frey's page.

【讨论】:

仅供参考,内核线程task-&gt;mm实际上是NULL【参考方案4】:

由于您将内核线程与用户[土地]线程进行比较,我假设您的意思类似于以下内容。

现在实现线程的正常方式是在内核中进行,所以这些可以被认为是“普通”线程。然而,也可以在用户空间中使用诸如 SIGALRM 之类的信号来执行此操作,其处理程序将保存当前进程状态(主要是寄存器)并将它们更改为先前保存的另一个状态。几个操作系统在获得适当的内核线程支持之前使用它作为实现线程的一种方式。它们可以更快,因为您不必进入内核模式,但实际上它们已经消失了。

还有协作用户态线程,其中一个线程运行直到它调用一个特殊函数(通常称为yield),然后以与上述SIGALRM 类似的方式切换到另一个线程。这里的优点是程序完全可以控制,当您有时间问题(例如游戏)时,这可能很有用。您也不必太在意线程安全。最大的缺点是一次只能运行一个线程,因此在处理器有多个内核的情况下,这种方法也不常见。

内核线程在内核中实现。也许您的意思是如何使用它们?最常见的方式是拨打pthread_create

【讨论】:

以上是关于什么是内核线程?的主要内容,如果未能解决你的问题,请参考以下文章

JVM线程与Linux内核线程的映射(关系)

Windows内核(驱动)编程中的线程问题

线程:为啥必须将所有用户线程映射到内核线程?

内核线程源码分析

内核线程源码分析

用户线程与内核线程如何映射?