Linux内核中创建线程

在Linux内核空间和用户空间创建线程的函数不一样。Linux内核下创建线程要先包含 linux/kthread.h头文件

内核线程创建:
kthread_create函数声明

struct task_struct *kthread_create(int (*threadfn)(void *data),
                   void *data,
                   const char namefmt[],
                   ...)

kthread_create函数创建线程后,线程并不会运行,在执行wake_up_process后线程才开始运行。

linux/kthread.h头文件有个宏定义kthread_run快速的完成了这两个步骤:

#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;                                   \ })

内核线程退出:
kthread_stop函数声明

int kthread_stop(struct task_struct *k);

该函数会给kthread_create创建的线程发送一个结束信号并一直等待线程退出后才返回。相应线程在结束前应该给kthread_stop回应结束标志,如果线程是用do_exit()退出的,则不会给kthread_stop回应结束标志,
如果线程在kthread_stop()调用 之前就结束,之后kthread_stop()再调用会发生可怕地事情——调用kthread_stop()的进程可能崩溃。
如果线程函数永远不返回并且不检查信号,它将永远都不会停止。

kthread_should_stop函数:

int kthread_should_stop(void)
{
    return to_kthread(current)->should_stop;
}

该函数查询并返回该线程结构体成员should_stop,如果kthread_stop()被调用过,则该函数返回true。

范例:

static struct task_struct *task_one = NULL; 

static int init_mymodule(void) 
{
    ...

    task_one = kthread_run(task_func, NULL, "task_name");

    ...
}

int task_func(void *data)
{
    int err = 0;
    ...

    while(!kthread_should_stop())
    {
        //在这里处理其他任务
        ...
    }

    return err;
}



static int exit_mymodule(void) 
{
    ...

    if(NULL != task_one)
    {
        kthread_stop(task_one);
        task_one = NULL;
    }

    ...
}

几个相关结构体:

struct kthread_create_info
{
    /* Information passed to kthread() from kthreadd. */
    int (*threadfn)(void *data);
    void *data;

    /* Result passed back to kthread_create() from kthreadd. */
    struct task_struct *result;
    struct completion done;

    struct list_head list;
};

struct kthread {
    int should_stop;
    void *data;
    struct completion exited;
};

struct task_struct {
    volatile long state;    /* -1 unrunnable, 0 runnable, >0 stopped */
    void *stack;
    atomic_t usage;
    unsigned int flags; /* per process flags, defined below */
    unsigned int ptrace;

    int lock_depth;     /* BKL lock depth */

#ifdef CONFIG_SMP
#ifdef __ARCH_WANT_UNLOCKED_CTXSW
    int oncpu;
#endif
#endif

    int prio, static_prio, normal_prio;
    unsigned int rt_priority;
    const struct sched_class *sched_class;
    struct sched_entity se;
    struct sched_rt_entity rt;

    ......

}

你可能感兴趣的:(linux,线程,kernel,linux内核)