gpt4 book ai didi

c - 在内核中处理线程的正确方法?

转载 作者:太空狗 更新时间:2023-10-29 16:34:02 29 4
gpt4 key购买 nike

我到处都看到了一些零散的信息,但我似乎无法得出一个最终答案。如何清理内核中的僵尸线程?

只是为了确定并产生在内核中处理线程的最终正确方法,我想更广泛地问这个问题。 如何在 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_createkthread_run等,应该有kthread_joinkthread_wait,但是有不是。 do_wait 似乎也有可能,但它不需要 struct task_struct *

此外,我不确定 do_exit 是否是个好主意,或者是否有必要。有人可以想出关于如何创建、终止和清理 kthread 的最小草图吗?

最佳答案

执行此操作的“正确”方法之一是让您的线程函数检查它是否 kthread_should_stop,如果它确实需要停止则简单地返回。

您不需要调用 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是在reset_init中的init/main.c中设置的。它运行 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 将被调用并返回值。无需自己动手。

关于c - 在内核中处理线程的正确方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10177641/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com