在本章节中,我们将探索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");
create_workqueue()
: 创建一个新的工作队列。INIT_DELAYED_WORK()
: 初始化一个延迟工作结构。queue_delayed_work()
: 调度延迟工作到工作队列中。cancel_delayed_work()
: 取消已调度的延迟工作。destroy_workqueue()
: 销毁工作队列。工作队列是Linux内核中强大的异步处理工具,适用于多种延迟任务场景。通过本示例,您学会了如何创建、调度和管理工作队列,并实现定期执行任务。掌握工作队列将有助于您编写更高效、可靠的内核驱动。