什么是内核线程?
我刚刚开始编写设备驱动程序和新线程,编写了很多文档来了解线程。 我还有一些疑惑。
- 什么是内核线程?
- 它与用户线程有何不同?
- 两个线程之间的关系是什么?
- 我该如何实现内核线程?
- 我在哪里可以看到实现的输出?
谁能帮我 ?。 谢谢。
内核线程是仅在内核模式下运行的内核任务; 它通常不是由fork()
或clone()
系统调用创建的。 一个例子是kworker
或kswapd
。
如果你不知道它们是什么,你可能不应该实现内核线程。
Google提供了很多关于内核线程的页面 ,例如Frey的页面 。
- 内核线程是没有用户空间组件的
task_struct
。 - 除了缺少用户空间之外,它还有不同的祖先(
kthreadd
内核线程而不是init
进程),并且由仅内核API而不是fork/exec
系统调用的clone
序列创建。 - 两个内核线程将
kthreadd
作为父级。 除此之外,内核线程与用户空间进程享有相同的“独立性”。 - 使用kthread.h头中的
kthread_run
函数/宏你很可能必须编写一个内核模块来调用这个函数,所以你应该看看Linux设备驱动程序 - 如果您指的是实现的文本输出(通过
printk
调用),您可以使用dmesg
命令在内核日志中看到此输出。
用户线程和堆栈:
每个线程都有自己的堆栈,因此它可以使用自己的局部变量,线程的共享全局变量,它们是linux可执行文件的.data或.bss部分的一部分。 由于线程共享全局变量,即当我们想要在multithreading应用程序中访问/修改全局变量时,我们使用mutex等同步机制。 局部变量是线程单个堆栈的一部分,因此不需要任何同步。
内核线程内核线程已经从需要在进程上下文中运行内核代码中脱颖而出。 内核线程是工作队列机制的基础。 本质上,线程内核是仅在内核模式下运行且没有用户地址空间或其他用户属性的线程。
要创建线程内核,请使用kthread_create():
#include 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]线程进行比较,因此我假设您的意思如下。
现在实现线程的正常方法是在内核中执行它,因此可以将它们视为“正常”线程。 然而,也可以使用SIGALRM之类的信号在userland中进行,其处理程序将保存当前进程状态(主要是寄存器)并将它们更改为先前保存的另一个进程状态。 一些操作系统使用它作为在获得适当的内核线程支持之前实现线程的方法。 它们可以更快,因为你不必进入内核模式,但在实践中它们已经逐渐消失。
还有一些协作用户态线程,其中一个线程运行直到它调用一个特殊函数(通常称为yield),然后以与上面的SIGALRM类似的方式切换到另一个线程。 这里的优点是程序是完全控制的,当你有时间问题时(例如游戏),它可能很有用。 您也不必太在意线程安全。 最大的缺点是一次只能运行一个线程,因此,由于处理器具有多个内核,因此这种方法也很少见。
内核线程在内核中实现。 也许你的意思是如何使用它们? 最常见的方法是调用pthread_create
。