我刚刚开始编写设备驱动程序和新线程编程,经历了许多文档以获得有关线程的想法。我还有一些疑惑。
- 什么是内核线程?。
- 它与用户线程的区别?。
- 两个线程之间的关系是什么?。
- 我该如何实现内核线程?。
- 我在哪里可以看到实施的输出?。
醇>
任何人都可以帮助我吗? 感谢。
答案 0 :(得分:16)
task_struct
,没有用户空间组件。kthreadd
内核线程而不是init
进程),并且由仅内核API而不是clone
的序列创建fork/exec
系统调用。kthreadd
作为父级。除此之外,内核线程与用户空间进程享有相同的“独立性”。kthread_run
函数/宏您很可能必须编写内核模块才能调用此函数,因此您应该查看Linux Device Drivers printk
调用),您可以使用dmesg
命令在内核日志中看到此输出。答案 1 :(得分:8)
内核线程是仅在内核模式下运行的内核任务;它通常不是由fork()
或clone()
系统调用创建的。一个例子是kworker
或kswapd
。
如果你不知道它们是什么,你可能不应该实现内核线程。
Google提供了很多关于内核线程的网页,例如: Frey's page
答案 2 :(得分:3)
用户线程和堆栈:
每个线程都有自己的堆栈,因此它可以使用自己的局部变量,线程的共享全局变量是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 :(得分:0)
由于您正在将内核线程与用户[land]线程进行比较,因此我假设您的意思如下:
现在实现线程的正常方法是在内核中执行它,因此可以将它们视为“正常”线程。然而,也可以使用SIGALRM之类的信号在userland中进行,其处理程序将保存当前进程状态(主要是寄存器)并将它们更改为先前保存的另一个进程状态。一些操作系统使用它作为在获得适当的内核线程支持之前实现线程的方法。它们可以更快,因为你不必进入内核模式,但实际上它们已经消失了。
还有合作的用户态线程,其中一个线程运行直到它调用一个特殊的函数(通常称为yield),然后以与上面的SIGALRM类似的方式切换到另一个线程。这里的优点是程序是完全控制的,当你有时间问题时(例如游戏),它可能很有用。您也不必太在意线程安全。最大的缺点是一次只能运行一个线程,因此,由于处理器有多个内核,因此这种方法也不常见。
内核线程在内核中实现。也许你的意思是如何使用它们?最常见的方式是致电pthread_create
。