工作队列(Workqueue)处理器

在本章节中,我们将探索Linux内核中的工作队列(Workqueue)机制,学习如何启动一个工作队列,并定期打印消息。工作队列是内核中用于延迟执行任务的一种重要机制,特别适合处理不需要立即执行但需要上下文切换的任务。

工作队列简介

工作队列是Linux内核提供的一种异步处理机制,允许将任务推迟到内核线程中执行。它常用于处理中断下半部、定时任务或其他需要延迟执行的操作。工作队列的主要优点包括:

工作队列的基本组件

组件 描述
工作(Work) 需要延迟执行的任务,通常是一个函数。
工作队列(Workqueue) 用于管理工作的队列,可以是内核共享的或自定义的。
工作线程(Worker Thread) 实际执行工作的内核线程。

实现一个定期打印消息的工作队列

以下是一个简单的工作队列示例,它定期打印一条消息到内核日志:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/workqueue.h>
#include <linux/slab.h>

static struct workqueue_struct *my_wq;
static struct delayed_work *my_dwork;

static void my_work_handler(struct work_struct *work) {
    printk(KERN_INFO "工作队列处理器:Hello from workqueue!\n");
    // 重新调度工作,实现定期执行(每2秒)
    queue_delayed_work(my_wq, my_dwork, msecs_to_jiffies(2000));
}

static int __init my_module_init(void) {
    // 创建自定义工作队列
    my_wq = create_workqueue("my_workqueue");
    if (!my_wq) {
        printk(KERN_ERR "无法创建工作队列\n");
        return -ENOMEM;
    }

    // 分配延迟工作结构
    my_dwork = kmalloc(sizeof(struct delayed_work), GFP_KERNEL);
    if (!my_dwork) {
        destroy_workqueue(my_wq);
        return -ENOMEM;
    }

    // 初始化延迟工作
    INIT_DELAYED_WORK(my_dwork, my_work_handler);

    // 首次调度工作(延迟0毫秒,立即执行)
    queue_delayed_work(my_wq, my_dwork, 0);

    printk(KERN_INFO "模块加载,工作队列已启动\n");
    return 0;
}

static void __exit my_module_exit(void) {
    // 取消所有 pending 的工作
    cancel_delayed_work(my_dwork);
    flush_workqueue(my_wq);
    destroy_workqueue(my_wq);
    kfree(my_dwork);
    printk(KERN_INFO "模块卸载,工作队列已清理\n");
}

module_init(my_module_init);
module_exit(my_module_exit);
MODULE_LICENSE("GPL");

工作队列处理流程

初始化工作队列 调度工作 执行工作函数 重新调度 清理工作队列

关键函数说明

注意:在实际项目中,应谨慎处理错误和资源清理,避免内存泄漏和系统不稳定。

总结

工作队列是Linux内核中强大的异步处理工具,适用于多种延迟任务场景。通过本示例,您学会了如何创建、调度和管理工作队列,并实现定期执行任务。掌握工作队列将有助于您编写更高效、可靠的内核驱动。