2011-03-12 82 views
22

我寫了下面的代碼來創建一個內核線程:如何停止rmmod上的Linux內核線程?

#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命令,我可以創建一個名爲「普拉迪普」內核線程,我可以使用 ps -ef命令來查看新的線程如下

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

與其父是kthreadd其PID爲2 但我不能停止給rmmod命令這個線程。它給出以下輸出:

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

有人可以請告訴我如何殺死這個線程?

回答

38

只應使用的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;                \ 
}) 

所以你創建線程和漏水其中之一:

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

我認爲終止一個線程的兩種選擇是:

  1. 當你完成時調用do_exit()
  2. 當另一個線程調用kthread_stop()時返回一個值。

希望解決這兩個小問題後,您將擁有一個功能主題創建者/收割者。

代碼
+0

我糾正了第一個問題,但我不明白的第二prbblem。你能否詳細解釋我的第二個問題。 – pradeepchhetri 2011-03-12 15:45:55

+1

@pradeepchhetri,你解決了你的問題嗎?對不起,我遺憾了差不多一個星期。關於終止線程,它看起來像只有兩個選擇:在線程函數中調用'do_exit()'(而不是從函數的尾部掉下來或試圖返回一個值);或定期輪詢'kthread_should_stop()':當它返回true時,則需要'返回0'(用於成功)或'返回'其中一個錯誤代碼。 – sarnold 2011-03-17 22:25:04

+0

嗨,我正在寫內核中的多線程密集型驅動程序。由於printk不能與內核線程一起工作,我如何通過內核線程記錄信息以便更容易調試? – 2017-03-09 16:14:15

0

ü不需要使用kthread_create API作爲kthread_run做它內部.. 二者必選其一

任務= kthread_create(& thread_function(void *的)數據, 「普拉迪普」);

task = kthread_run(& thread_function,(void *)data,「pradeep」);

此外您的模塊不符合GPL許可證。這可能是你的問題的一個原因。

+0

'任務= kthread_create(thread_function,(無效*)的數據, 「與Pradeep」);' 'wake_up_process(任務)' ** OR ** '任務= kthread_run(thread_function,(無效*)的數據, 「與Pradeep」);' – Jayzcode 2017-03-06 07:16:29

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");