Linux 两种方式创建内核线程

kernel_thread()、daemonize()
------------------------------------------------------
int thread_func(void *arg)
{
    /*
     * 设置线程名 -- thread_name,ps可以看到的线程名
     * 如果不使用daemonize设置内核线程名,并且kernel_thread()
     * 是用户态程序通过系统调用使用的,则ps将看到一个和用户进程同名
     * 的一个内核线程。
     */
    daemonize("thread_name");
    return 0;
}

 

{
    pid_t pid;
    /* 创建内核线程 */
    pid = kernel_thread(thread_func, NULL, CLONE_KERNEL);
    if (pid < 0)
    {
        printk("kernel_thread error\n");
    }
}

 

 

 

kthread_run() -- 这种创建方式比较简洁
------------------------------------------------------
int thread_func(void *arg)
{
    return 0;
}


{
    struct task_struct * my_thread = NULL;

    my_thread = kthread_run(thread_func, NULL, "thread_name");
    if (IS_ERR(my_thread))
    {
        rc = PTR_ERR(my_thread);
        printk("error %d create thread_name thread", rc);
    }
}

 

 

 

 

 

 

 

 

kernel_thread()类似application编程里面的fork()
------------------------------------------------------
static int jffs2_garbage_collect_thread(void *_c)
{
    ...
    daemonize("jffs2_gcd_mtd%d", c->mtd->index);
    ...
    complete(&c->gc_thread_start);
    ...
}


int jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c)
{
    pid_t pid;
    int ret = 0;

    BUG_ON(c->gc_task);

    init_completion(&c->gc_thread_start);
    init_completion(&c->gc_thread_exit);

    pid =kernel_thread(jffs2_garbage_collect_thread, c, CLONE_FS|CLONE_FILES);
    if (pid < 0) {  // 判断出错条件
        printk(KERN_WARNING "fork failed for JFFS2 garbage collect thread: %d\n", -pid);
        complete(&c->gc_thread_exit);
        ret = pid;
    } else {        // pid > 0 ,说明这个肯定在父进程中
        printk(KERN_DEBUG "JFFS2: Garbage collect thread is pid %d\n", pid);
        wait_for_completion(&c->gc_thread_start); //父进程等待子进程结束
    }

    return ret;
}