zoukankan      html  css  js  c++  java
  • 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的使用

    未完待续。。。。。

  • 相关阅读:
    Node项目
    Angular模块/服务/MVVM
    Angular介绍1
    Node环境配置及Gulp工具
    Linux及Git介绍
    数据库MySQL
    ReactiveCocoa 监听枚举类型enumerate 或者 NSInteger类型
    ReactiveCocoa 监听布尔(BOOL)类型改变
    python3.7 urlopen请求HTTPS警告'CERTIFICATE_VERIFY_FAILED'解决办法
    Centos yum命令
  • 原文地址:https://www.cnblogs.com/hellokitty2/p/10982219.html
Copyright © 2011-2022 走看看