Linux内核中创建线程

来源:互联网 发布:山东网络教育大学 编辑:程序博客网 时间:2024/06/05 20:06

在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;    ......}
0 0