只是为了确保,并产生一个最终正确的处理内核线程的方式,我想更广泛地提出这个问题.如何在Linux内核中创建,终止和清理线程?
我到目前为止是这样的:
thread_func: exited = 0; while (!must_exit) do stuff exited = 1; do_exit(0) init_module: must_exit = 0; exited = 1; kthread_run(thread_func,...) /* creates and runs the thread */ cleanup_module: must_exit = 1; while (!exited) set_current_state(TASK_INTERRUPTIBLE); msleep(1); /* How do I cleanup? */
我找到的最清晰的解决方案是release_task,但我没有发现任何地方谈论它.我想象,因为线程函数是kthread_create,kthread_run等,应该有一个kthread_join或kthread_wait,但没有. do_wait也似乎很可能,但它并不需要struct task_struct *.
此外,我不知道do_exit是一个好主意,或者如果还有必要的话.有人可以提出一个kthread应如何创建,终止和清理的最小草图?
解决方法
你不需要调用do_exit,如果你打算从模块退出函数kthread_stop,你可能不应该.
您可以通过查看kernel/kthread.c
中kthread_create_on_node的文档(从Linux内核3.3.1中提取)来看到这一点:
/**
* kthread_create_on_node – create a kthread.
* @threadfn: the function to run until signal_pending(current).
* @data: data ptr for @threadfn.
* @node: memory node number.
* @namefmt: printf-style name for the thread.
*
* Description: This helper function creates and names a kernel
* thread. The thread will be stopped: use wake_up_process() to start
* it. See also kthread_run().
*
* If thread is going to be bound on a particular cpu,give its node
* in @node,to get NUMA affinity for kthread stack,or else give -1.
* When woken,the thread will run @threadfn() with @data as its
* argument. @threadfn() can either call do_exit() directly if it is a
* standalone thread for which no one will call kthread_stop(),or
* return when ‘kthread_should_stop()’ is true (which means
* kthread_stop() has been called). The return value should be zero
* or a negative error number; it will be passed to kthread_stop().
*
* Returns a task_struct or ERR_PTR(-ENOMEM).
*/
kthread_stop存在“匹配”注释:
If threadfn() may call do_exit() itself,the caller must ensure task_struct can’t go away.
(我不知道你怎么做 – 可能用一个get_task_struct来保存struct_task.)
如果你走线程创建的路径,你会得到如下的东西:
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)
所以如果你的_thread_function简单的返回,do_exit将被调用返回值.没有必要自己去做