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

未完待续。。。。。

 

posted on   Hello-World3  阅读(3308)  评论(0编辑  收藏  举报

编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示