我刚开始编写设备驱动程序,对线程很陌生,为了了解线程,我查阅了许多文档。我仍然有一些疑虑。
- 什么是内核线程
- 它与用户线程有何不同
- 这两条线索之间的关系是什么
- 如何实现内核线程
- 在哪里可以看到实现的输出
有人能帮我吗?谢谢
- 内核线程是一个没有用户空间组件的
task_struct
- 除了缺乏用户空间之外,它还具有不同的祖先(
kthreadd
内核线程而不是init
进程),并且由仅内核的API创建,而不是由fork/exec
系统调用的clone
序列创建 - 两个内核线程将
kthreadd
作为父线程。除此之外,内核线程享受相同的";独立性";一个从另一个作为用户空间进程 - 使用kthread.h标头中的
kthread_run
函数/宏您很可能需要编写一个内核模块才能调用此函数,因此您应该查看Linux设备驱动程序 - 如果您引用实现的文本输出(通过
printk
调用),则可以使用dmesg
命令在内核日志中看到该输出
内核线程是仅在内核模式下运行的内核任务;它通常不是由CCD_ 10或CCD_。例如kworker
或kswapd
。
如果您不知道内核线程是什么,那么您可能不应该实现它们。
谷歌提供了许多关于内核线程的页面,例如弗雷的页面。
用户线程&堆栈:
每个线程都有自己的堆栈,这样它就可以使用自己的局部变量,线程的共享全局变量是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
由于您将内核线程与用户[land]线程进行比较,我认为您的意思如下。
现在实现线程的正常方式是在内核中实现,因此这些线程可以被视为"正常"线程。然而,也可以在userland中使用SIGALRM等信号来执行此操作,SIGALRM的处理程序将保存当前进程状态(主要是寄存器),并将其更改为以前保存的另一个状态。一些操作系统在获得适当的内核线程支持之前就将此作为实现线程的一种方式。它们可以更快,因为你不必进入内核模式,但在实践中它们已经消失了。
还有协作的userland线程,其中一个线程运行,直到它调用一个特殊的函数(通常称为yield),然后该函数以与上述SIGALRM类似的方式切换到另一个线程。这里的优点是该程序完全可以控制,当你有时间问题(例如游戏)时,这会很有用。您也不必太关心线程安全性。最大的缺点是一次只能运行一个线程,因此这种方法在处理器有多个内核的情况下也不常见。
内核线程是在内核中实现的。也许你的意思是如何使用它们?最常见的方法是调用pthread_create
。