执行此操作的“正确”方法之一是让您的线程函数检查它是否kthread_should_stop
,如果它确实需要停止则简单地返回。
你不需要调用do_exit
,如果你打算kthread_stop
从模块退出函数调用它,你可能不应该。
您可以通过查看kthread_create_on_node
in的文档来了解这一点kernel/kthread.c
(从 Linux 内核 3.3.1 中提取):
/**
* kthread_create_on_node - 创建一个 kthread。
* @threadfn:在 signal_pending(current) 之前运行的函数。
* @data:@threadfn 的数据指针。
* @node:内存节点号。
* @namefmt:线程的 printf 样式名称。
*
* 描述:此辅助函数创建并命名内核
* 线程。线程将被停止:使用 wake_up_process() 来启动
它。另请参见 kthread_run()。
*
* 如果线程要绑定在特定的 cpu 上,
则在 @node 中给它的节点 *,以获得 kthread 堆栈的 NUMA 亲和性,否则给 -1。
* 当被唤醒时,线程将运行 @threadfn() 并使用 @data 作为它的
* 参数。@threadfn() 可以直接调用 do_exit() 如果它是一个没有人会调用 kthread_stop() 的独立线程,或者
*当 'kthread_should_stop()' 为真时返回(这意味着
*
kthread_stop() 已被调用) . 返回值应为零
* 或负错误号;它将被传递给 kthread_stop()。
*
* 返回一个 task_struct 或 ERR_PTR(-ENOMEM)。
*/
存在“匹配”评论kthread_stop
:
如果 threadfn() 可能调用 do_exit() 本身,调用者必须确保 task_struct 不能消失。
(而且我不确定你是怎么做到的 - 可能会坚持struct_task
使用get_task_struct
.)
如果你走线程创建的路径,你会得到类似的东西:
kthread_create // macro in kthread.h
-> kthread_create_on_node // in kthead.c
-> adds your thread request to kthread_create_list
-> wakes up the kthreadd_task
kthreadd_task
设置在init/main.c
中reset_init
。它运行kthreadd
函数(来自kthread.c
)
kthreadd // all in kthread.c
-> create_kthread
-> kernel_thread(kthread, your_kthread_create_info, ...)
kthread
函数本身会:
kthread
-> initialization stuff
-> schedule() // allows you to cancel the thread before it's actually started
-> if (!should_stop)
-> ret = your_thread_function()
-> do_exit(ret)
...因此,如果your_thread_function
只是返回,do_exit
将以其返回值调用。不需要自己做。