linux 核心線程

來源:互聯網
上載者:User

建立核心線程:
 struct task_struct *kthread_create(int (*threadfn)(void *data),
   void *data, const char namefmt[]);
 
喚醒核心線程(可以喚醒所有進程(線程)):
 wake_up_process(struct task_struct *k);

建立並運行核心線程:
 struct task_struct *kthread_run(int (*threadfn)(void *data),
   void *data, const char namefmt[]);

通知核心線程停止:
 int kthread_stop(struct task_struct *k);
 返回threadfn函數的傳回值, 如果k沒有被wake_up_process(k)過將返回-EINTR
 不是強制停止, 如果核心線程不停止將一直等待

檢查是否收到停止訊號:
 int kthread_should_stop(void);

 

kthread_create與kernel_thread的區別

從表面上來看,這兩個函數非常的類似,但是實現卻是相差甚遠。
kthread_create是通過work_queue來實現的,kernel_thread是通過do_fork來實現的。

 

kernel thread可以用kernel_thread建立,但是在執行函數裡面必須用daemonize釋放資源並掛到init下,還需要用 completion等待這一過程的完成。

kthread_create是比較正牌的建立函數,這個不必要調用daemonize,用這個建立的kernel thread都掛在了kthread線程下。

 

 

 

 

可以在非核心線程中調用kernel_thread, 但這樣建立的線程必須在自己調用daemonize(...)來釋放資源,成為真正的核心線程。

#include <linux/kernel.h>
#include <linux/module.h>
static int noop(void *dummy)
{
        int i = 0;
        daemonize("mythread");
        while(i++ < 5) {
                printk("current->mm = %p\n", current->mm);
                printk("current->active_mm = %p\n", current->active_mm);
                set_current_state(TASK_INTERRUPTIBLE);
                schedule_timeout(10 * HZ);
        }
        return 0;
}
static int test_init(void)
{
        kernel_thread(noop, NULL, CLONE_KERNEL | SIGCHLD);
        return 0;
}
static void test_exit(void) {}
module_init(test_init);
module_exit(test_exit);

”mythread“就是給這個核心線程取的名字, 可以用ps -A來查看。
schedule()用於進程調度, 可以理解為放棄CPU的使用權.

 

 

 

 

 kthread_create建立線程

1 使用kthread_create建立線程:
    struct task_struct *kthread_create(int (*threadfn)(void *data),                                             void *data,
                                            const char *namefmt, ...);
這個函數可以像printk一樣傳入某種格式的線程名
線程建立後,不會馬上運行,而是需要將kthread_create() 返回的task_struct指標傳給wake_up_process(),然後通過此函數運行線程。
2. 當然,還有一個建立並啟動線程的函數:kthread_run
   struct task_struct *kthread_run(int (*threadfn)(void *data),
                                    void *data,
                                    const char *namefmt, ...);
3. 線程一旦啟動起來後,會一直運行,除非該線程主動調用do_exit函數,或者其他的進程調用kthread_stop函數,結束線程的運行。
    int kthread_stop(struct task_struct *thread);
kthread_stop() 通過發送訊號給線程。
如果線程函數正在處理一個非常重要的任務,它不會被中斷的。當然如果線程函數永遠不返回並且不檢查訊號,它將永遠都不會停止。
參考:Kernel threads made easy -- view plaincopy to clipboardprint?
#include <linux/kthread.h>  
static struct task_struct * _task;  
static struct task_struct * _task2;  
static struct task_struct * _task3;  
static int thread_func(void *data)  
{  
        int j,k;  
        int timeout;  
        wait_queue_head_t timeout_wq;  
        static int i = 0;         
        i++;  
        j = 0;  
        k = i;  
        printk("thread_func %d started\n", i);  
        init_waitqueue_head(&timeout_wq);  
        while(!kthread_should_stop())  
        {  
                interruptible_sleep_on_timeout(&timeout_wq, HZ);  
                printk("[%d]sleeping..%d\n", k, j++);  
        }  
        return 0;  
}  
void my_start_thread(void)  
{  
          
        //_task = kthread_create(thread_func, NULL, "thread_func2");  
        //wake_up_process(_task);  
        _task = kthread_run(thread_func, NULL, "thread_func2");  
        _task2 = kthread_run(thread_func, NULL, "thread_func2");  
        _task3 = kthread_run(thread_func, NULL, "thread_func2");  
        if (!IS_ERR(_task))  
        {  
                printk("kthread_create done\n");  
        }  
        else 
        {  
                printk("kthread_create error\n");  
        }  
}  
void my_end_thread(void)  
{  
        int ret = 0;  
        ret = kthread_stop(_task);  
        printk("end thread. ret = %d\n" , ret);  
        ret = kthread_stop(_task2);  
        printk("end thread. ret = %d\n" , ret);  
        ret = kthread_stop(_task3);  
        printk("end thread. ret = %d\n" , ret);  

#include <linux/kthread.h>
static struct task_struct * _task;
static struct task_struct * _task2;
static struct task_struct * _task3;
static int thread_func(void *data)
{
        int j,k;
        int timeout;
        wait_queue_head_t timeout_wq;
        static int i = 0;      
        i++;
        j = 0;
        k = i;
        printk("thread_func %d started\n", i);
        init_waitqueue_head(&timeout_wq);
        while(!kthread_should_stop())
        {
                interruptible_sleep_on_timeout(&timeout_wq, HZ);
                printk("[%d]sleeping..%d\n", k, j++);
        }
        return 0;
}
void my_start_thread(void)
{
       
        //_task = kthread_create(thread_func, NULL, "thread_func2");
        //wake_up_process(_task);
        _task = kthread_run(thread_func, NULL, "thread_func2");
        _task2 = kthread_run(thread_func, NULL, "thread_func2");
        _task3 = kthread_run(thread_func, NULL, "thread_func2");
        if (!IS_ERR(_task))
        {
                printk("kthread_create done\n");
        }
        else
        {
                printk("kthread_create error\n");
        }
}
void my_end_thread(void)
{
        int ret = 0;
        ret = kthread_stop(_task);
        printk("end thread. ret = %d\n" , ret);
        ret = kthread_stop(_task2);
        printk("end thread. ret = %d\n" , ret);
        ret = kthread_stop(_task3);
        printk("end thread. ret = %d\n" , ret);
} 在執行kthread_stop的時候,目標線程必須沒有退出,否則會Oops。原因很容易理解,當目標線程退出的時候,其對應的task結構也變得無效,kthread_stop引用該無效task結構就會出錯。 為了避免這種情況,需要確保線程沒有退出,其方法如代碼中所示: thread_func() {     // do your work here     // wait to exit     while(!thread_could_stop())     {            wait();     } } exit_code() {      kthread_stop(_task);   //發訊號給task,通知其可以退出了 } 這種退出機制很溫和,一切盡在thread_func()的掌控之中,線程在退出時可以從容地釋放資源,而不是莫名其妙地被人“暗殺”。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.