在内核线程处理适当的方式? [英] Proper way of handling threads in kernel?

查看:139
本文介绍了在内核线程处理适当的方式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我见过的零散信息位周围的一切,但我似乎无法得到一个最终的答案。你如何清理僵尸线程内核?

I've seen bits of scattered information all around, but I can't seem to get to one final answer. How do you clean up a zombie thread in kernel?

只是为了确保和生产处理的内核线程最后正确的方法,我想更广泛地问这个问题。 如何创建,终止并清理线程在Linux内核?

Just to make sure, and produce a final correct way of handling threads in kernel, I would like to ask this question more broadly. How do you create, terminate and clean up a thread in the Linux kernel?

我到目前为止是这样的:

What I have so far is this:

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 也似乎有可能,但它并不需要一个结构的task_struct *

The closest thing I have found to the cleanup solution is release_task, but I didn't find anywhere talking about it. I imagined since the thread functions are kthread_create, kthread_run etc, there should be a kthread_join or kthread_wait, but there wasn't. do_wait also seemed likely, but it doesn't take a struct task_struct *.

此外,我不知道,如果 do_exit 是一个好主意,或者如果在所有必要无论是。可有人请拿出一个KTHREAD应该如何创建,终止和清理?最小小品

Furthermore, I am not sure if do_exit is a good idea, or if at all necessary either. Can someone please come up with the minimum sketch of how a kthread should be created, terminated and cleaned up?

推荐答案

其中的正确的方式来做到这一点是让你的线程函数检查它是否 kthread_should_stop ,并简单地返回,如果它确实需要停下来。

One of the "right" ways to do this is to have your thread function check if it kthread_should_stop, and simply return if it does need to stop.

您不需要从模块退出函数调用 do_exit ,如果你打算 kthread_stop 它,你可能不应该的。

You don't need to call do_exit, and if you intend to kthread_stop it from the module exit function, you probably shouldn't.

您可以通过在文档中的 kthread_create_on_node 看到这个=htt​​p://lxr.free-electrons.com/source/kernel/kthread .C> 内核/ kthread.c (从Linux内核3.3.1提取物):

You can see this by looking at the documentation for kthread_create_on_node in kernel/kthread.c (extract from Linux kernel 3.3.1):

/ **结果
   * kthread_create_on_node - 创建一个KTHREAD结果。
   * @threadfn:运行,直到signal_pending(电流)功能结果。
   * @data:PTR数据为@threadfn结果。
   * @node:存储节点号结果。
   * @namefmt:printf风格的名称线程结果。
   *结果
   *说明:此辅助函数创建并命名内核结果
   *线程。该线程将停止:使用wake_up_process()开始结果
   *它。另请参见kthread_run()。结果
   *结果
   *如果螺纹是要在一个特定的CPU被束缚,给其节点搜索
   *在@node,获得NUMA亲和力KTHREAD堆栈,否则会给-1。结果
   *当唤醒,该线程将运行@threadfn()与@data作为其结果
   *参数。 @threadfn()可以调用do_exit()直接,如果它是一个结果
   * 独立的线程没有人会调用kthread_stop(),或结果
   * 返回时'kthread_should_stop()'是真的(这意味着结果
   * kthread_stop()被调用)。返回值应该为零结果
   *或负的错误号;它会被传递给kthread_stop()。结果
   *结果
   *返回的task_struct或ERR_PTR(-ENOMEM)。结果
   * /

/**
* 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).
*/

一个匹配的评论是present kthread_stop

A "matching" comment is present for kthread_stop:

如果threadfn()可以调用do_exit()本身,调用者必须确保的task_struct不能走

If threadfn() may call do_exit() itself, the caller must ensure task_struct can't go away.

(我不知道你怎么做到这一点 - 也许持有到 struct_task get_task_struct 。)

(And I'm not sure how you do that - probably holding on to the struct_task with a get_task_struct.)

如果你走一个线程创建的,你就会得到这样的路径:

If you walk the path of a thread creation you'll get something like:

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_task is set up in init/main.c in reset_init. It runs the kthreadd function (from 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 将其返回值调用。不需要自己做。

... So if your_thread_function simply returns, do_exit will be called with its return value. No need to do it yourself.

这篇关于在内核线程处理适当的方式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆