Linux 的内核线程实际上是只存在于内核空间的一个进程。内核通常创建内核线程, 让它在后台周期性的处理一些事务。内核线程和普通进程一样可调度,可被抢先。他们的最显著的区别是内核线程的进程描述结构体 task_struct 的 mm 字段为 NULL。而一般进程的进程描述结构体的 mm 字段指向该进程的地址空间。因为内核线程永远只运行在内核态,永远不必切换至用户空间,并且所有用户态进程的地址空间的内核虚拟地址部分都是一样的,所以当处理器调度到内核进程时,内核进程可以随便使用某个用户态进程的地址空间的内核虚拟地址部分。Linux 内核线程的作法是借用上一个普通用户态进程的用户空间。
实现
内核线程由内核 API 函数 kthread_create()创建,也可由 kthread_run()创建。他们的区别是前者创建的是一个处于非运行状态的内核线程,需要使wake_up_process()把它转换为可运行状态;而 kthread_run()创建的内核线程立即处于可运行状态,随时可能被调度而获得运行的机会。内核线程开始后会一直运行,直到它显式地调用 do_exit()或者其它内核代码调用 kthread_stop()。kthread_stop()函数需要传入先前创建内核线程函数返回的 task_struct 作为参数。该函数在调用后会一直阻塞,直到等待的内核线程完全退出了才返回。