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

前端之家收集整理的这篇文章主要介绍了c – 在内核中处理线程的正确方法?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我已经看到一些分散的信息,但我似乎无法得到一个最后的答案.如何清理内核中的僵尸线程?

只是为了确保,并产生一个最终正确的处理内核线程的方式,我想更广泛地提出这个问题.如何在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应如何创建,终止和清理的最小草图?

解决方法

执行此操作的“正确”方法之一是让您的线程函数检查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在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将被调用返回值.没有必要自己去做

猜你在找的C&C++相关文章