Skip to main content
 首页 » 操作系统

Linux worker线程的创建与使用

2022年07月19日172birdshome

一、worker线程的创建

1. 创建流程

//调用这个接口创建内核工作线程,eg: crypto_engine.c中的创建方法: 
kthread_create_worker(0, "%s", engine->name); //在CPU0上创建一个work线程 
    kthread_create_worker(unsigned int flags, const char namefmt[], ...) 
    //或kthread_create_worker_on_cpu(int cpu, unsigned int flags, const char namefmt[], ...) 
        __kthread_create_worker(int cpu, unsigned int flags, const char namefmt[], va_list args) 
            __kthread_create_on_node(kthread_worker_fn, worker, node, namefmt, args)

__kthread_create_worker():

/* 若是参数cpu大于等于0就创建特定于某个CPU的工作线程,若是不想创建特定于CPU的工作线程,就将CPU域赋值为-1 */ 
static struct kthread_worker * __kthread_create_worker(int cpu, unsigned int flags, const char namefmt[], va_list args) 
{ 
    struct kthread_worker *worker; 
    struct task_struct *task; 
    int node = -1; 
 
    worker = kzalloc(sizeof(*worker), GFP_KERNEL); 
    if (!worker) 
        return ERR_PTR(-ENOMEM); 
 
    kthread_init_worker(worker); 
 
    if (cpu >= 0) 
        node = cpu_to_node(cpu); 
 
    task = __kthread_create_on_node(kthread_worker_fn, worker, 
                        node, namefmt, args); 
    if (IS_ERR(task)) 
        goto fail_task; 
 
    if (cpu >= 0) 
        kthread_bind(task, cpu); 
 
    worker->flags = flags; 
    worker->task = task; 
    wake_up_process(task); 
    return worker; 
 
fail_task: 
    kfree(worker); 
    return ERR_CAST(task); 
}

kthread_worker_fn 循环监听是否有工作需要处理: 

int kthread_worker_fn(void *worker_ptr) 
{ 
    struct kthread_worker *worker = worker_ptr; 
    struct kthread_work *work; 
 
    /* 
     * FIXME: Update the check and remove the assignment when all kthread 
     * worker users are created using kthread_create_worker*() functions. 
     */ 
    WARN_ON(worker->task && worker->task != current); 
    worker->task = current; 
 
    if (worker->flags & KTW_FREEZABLE) 
        set_freezable(); 
 
repeat: 
    /* 设置进程的状态,不被调度 */ 
    set_current_state(TASK_INTERRUPTIBLE);    /* mb paired w/ kthread_stop */ 
 
    if (kthread_should_stop()) { 
        __set_current_state(TASK_RUNNING); 
        spin_lock_irq(&worker->lock); 
        worker->task = NULL; 
        spin_unlock_irq(&worker->lock); 
        return 0; 
    } 
 
    work = NULL; 
    spin_lock_irq(&worker->lock); 
    if (!list_empty(&worker->work_list)) { 
        /* 从work_list中取出一个工作 */ 
        work = list_first_entry(&worker->work_list, struct kthread_work, node); 
        list_del_init(&work->node); 
    } 
    worker->current_work = work; 
    spin_unlock_irq(&worker->lock); 
 
    if (work) { 
        __set_current_state(TASK_RUNNING); 
        /* 执行这个工作上func() */ 
        work->func(work); 
    } else if (!freezing(current)) 
        schedule(); 
 
    try_to_freeze(); 
    cond_resched(); 
 
    /* 又跳到repeat位置,进行循环执行 */ 
    goto repeat; 
}

二、worker的使用

未完待续。。。。。


本文参考链接:https://www.cnblogs.com/hellokitty2/p/10982219.html