23

カーネルスレッドを作成するために、次のコードを記述しました。

#include<linux/init.h>
#include<linux/module.h>
#include<linux/kernel.h>
#include<linux/kthread.h>
#include<linux/sched.h>

struct task_struct *task;
int data;
int ret;
int thread_function(void *data)
{
    int var;
    var = 10;
    return var;
}

static int kernel_init(void)
{
    data = 20;
    printk(KERN_INFO"--------------------------------------------");
    task = kthread_create(&thread_function,(void *)data,"pradeep");
    task = kthread_run(&thread_function,(void *)data,"pradeep");
    printk(KERN_INFO"Kernel Thread : %s\n",task->comm);
    return 0;
}

static void kernel_exit(void)
{
    ret = kthread_stop(task);
}

module_init(kernel_init);
module_exit(kernel_exit);

insmodコマンドを実行すると、「pradeep」という名前のカーネルスレッドを作成でき、 ps -ef次のコマンドを使用して新しいスレッドを確認できます。

root      6071     2  0 10:21 ?        00:00:00 [pradeep]

その親はKthreaddであり、そのPIDは2です。しかし、rmmodコマンドを実行してもこのスレッドを停止することはできません。次の出力が得られます。

ERROR: Removing 'pradeep': Device or resource busy.

誰かがこのスレッドを殺す方法を教えてもらえますか?

4

3 に答える 3

40

kthread_create()またはのいずれかのみを使用する必要がありますkthread_run()

/**
 * kthread_run - create and wake a thread.
 * @threadfn: the function to run until signal_pending(current).
 * @data: data ptr for @threadfn.
 * @namefmt: printf-style name for the thread.
 *
 * Description: Convenient wrapper for kthread_create() followed by
 * wake_up_process().  Returns the kthread or ERR_PTR(-ENOMEM).
 */
#define kthread_run(threadfn, data, namefmt, ...)                      \
({                                                                     \
    struct task_struct *__k                                            \
            = kthread_create(threadfn, data, namefmt, ## __VA_ARGS__); \
    if (!IS_ERR(__k))                                                  \
            wake_up_process(__k);                                      \
    __k;                                                               \
})

したがって、2つのスレッドを作成し、そのうちの1つをリークしています。

task = kthread_create(&thread_function,(void*) &data,"pradeep");
task = kthread_run(&thread_function,(void*) &data,"pradeep");

さらに、スレッド関数にいくつかの詳細が欠落している可能性があります。

/**
 * kthread_create - create a kthread.
 * @threadfn: the function to run until signal_pending(current).
 * @data: data ptr for @threadfn.
 * @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().
 *
 * 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 noone 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).
 */

スレッドを終了するための2つの選択肢は次のとおりです。

  1. 終わったら電話do_exit()してください。
  2. 別のスレッドが。を呼び出したときに値を返しますkthread_stop()

うまくいけば、これら2つの小さな問題を修正した後、機能的なスレッドクリエーター/リーパーができます。

于 2011-03-12T05:25:41.220 に答える
5

以下のプログラムがあなたの問題を解決することを願っています....親指を立てる:-)

`#include<linux/init.h>
 #include<linux/module.h>
 #include<linux/kernel.h>
 #include<linux/kthread.h>
 #include<linux/sched.h>`

struct task_struct *task;
int data;
int ret;
int thread_function(void *data)
{
  int var;
 var = 10;
     printk(KERN_INFO "IN THREAD FUNCTION");
     while(!kthread_should_stop()){
             schedule();
             }
     /*do_exit(1);*/
  return var;

}

static int kernel_init(void)
{
   data = 20;
   printk(KERN_INFO"--------------------------------------------");
   /*task = kthread_create(&thread_function,(void *)data,"pradeep");*/
   task = kthread_run(&thread_function,(void *)data,"pradeep");
   printk(KERN_INFO"Kernel Thread : %s\n",task->comm);
   return 0;
}

static void kernel_exit(void)
{
   kthread_stop(task);
}

module_init(kernel_init);
module_exit(kernel_exit);
MODULE_AUTHOR("SHRQ");
MODULE_LICENSE("GPL");
于 2014-07-30T21:02:34.650 に答える
0

コードでは、内部で使用するようにkthread_createapiを使用する必要はありません。どちらかを使用してください。kthread_run

task = kthread_create(&thread_function、(void *)data、 "pradeep");
または
task=kthread_run(&thread_function、(void *)data、 "pradeep");

また、モジュールはGPLライセンスの下にありません。それが問題の原因の1つである可能性があります。

于 2014-02-27T15:02:38.157 に答える