• worker线程的创建与使用


    一、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的使用

    未完待续。。。。。

  • 相关阅读:
    设计模式-观察者模式
    获取ubuntu中软件包的有用地址
    vim 简单命令
    adb logcat 日志过滤
    shell编程——
    shell编程——参数传递
    Chromecast
    linux 广播
    【转】Git命令解说
    linux 多播
  • 原文地址:https://www.cnblogs.com/hellokitty2/p/10982219.html
Copyright © 2020-2023  润新知