Linux 驱动中 Timer / Tasklet / Workqueue 的作用与对比
🧩 1. 使用场景概览(对比表)
机制 |
执行上下文 |
是否可睡眠 |
使用场景 |
常用接口 |
Timer |
中断上下文 |
❌ 不可睡眠 |
延迟执行(如防抖、超时处理) |
add_timer() 等 |
Tasklet |
软中断上下文 |
❌ 不可睡眠 |
中断后的轻量快速处理 |
tasklet_schedule() |
Workqueue |
进程上下文 |
✅ 可睡眠 |
可阻塞、耗时操作(如 I/O) |
schedule_work() 等 |
🧠 2. 各机制作用详解
🔧 Timer(定时器)
- 作用:延迟执行某个函数,常用于按键防抖、超时控制等
- 上下文:中断上下文(不可睡眠)
- 示例:
struct timer_list my_timer;
timer_setup(&my_timer, my_timer_handler, 0);
mod_timer(&my_timer, jiffies + msecs_to_jiffies(20));
⚡ Tasklet(软中断)
- 作用:将中断处理函数中不能做的工作,延后到软中断上下文处理。
- 上下文:软中断上下文(不可阻塞)。
示例:
struct tasklet_struct tasklet;
DECLARE_TASKLET(my_tasklet, tasklet_handler, data);
tasklet_schedule(&my_tasklet);
🧵 Workqueue(工作队列)
- 作用:将任务放到内核线程中执行,可以使用阻塞操作,适合复杂或耗时的任务。
- 上下文:进程上下文(可阻塞)。
示例:
struct work_struct work;
void work_handler(struct work_struct *work) {
printk(KERN_INFO "Work handler executed\n");
}
INIT_WORK(&my_work, work_handler);
schedule_work(&my_work);
三种方式调用func示例:
static irqreturn_t gpio_key_isr(int irq, void *dev_id)
{
struct gpio_key *gpio_key = dev_id;
tasklet_schedule(&gpio_key->tasklet);
mod_timer(&gpio_key->key_timer, jiffies + HZ/50);
schedule_work(&gpio_key->work);
return IRQ_HANDLED;
}