Linux驱动如何唤醒睡眠kthread解决自动手动模式切换延迟问题
问题根因
你当前使用的msleep_interruptible()仅支持超时唤醒或通用信号唤醒,没有主动触发唤醒的自定义入口,kthread_stop()发出的停止信号无法立刻打断该休眠,必须等超时时间到后线程才会执行停止判断,导致切换延迟。
修复方案
使用等待队列+超时等待替换msleep_interruptible(),在触发手动模式切换时主动唤醒休眠线程,即可实现无延迟停止。
具体修改步骤
- 新增全局等待队列头定义,用于自定义唤醒事件
static DECLARE_WAIT_QUEUE_HEAD(fan_thread_wq);
- 修改温度检测线程的休眠逻辑,替换
msleep_interruptible()为可主动唤醒的超时等待:
int temperature(void *arg) { while (!kthread_should_stop()) { mutex_lock(&mutex); get_temperature(); mutex_unlock(&mutex); /* 替换原有msleep_interruptible:等待超时或者停止信号触发唤醒 */ wait_event_interruptible_timeout(fan_thread_wq, kthread_should_stop(), msecs_to_jiffies(polling_interval)); } return 0; }
- 在调用
kthread_stop()前先主动唤醒等待队列上的线程:
case MANUAL: if (control) { /* 先主动唤醒休眠的线程,让它立刻检查停止标记 */ wake_up(&fan_thread_wq); kthread_stop(control); control = NULL; printk(KERN_ALERT "Switching to MANUAL disabling kernel thread for Automatic\n"); } mode = MANUAL_MODE; printk(KERN_ALERT "IN MANUAL \n"); break;
注意事项
wait_event_interruptible_timeout()的第三个参数需要将毫秒转为jiffies单位,直接调用内核提供的msecs_to_jiffies()即可适配不同内核的时钟配置- 该方案不需要修改原有自动模式的业务逻辑,仅调整休眠和停止触发逻辑,兼容性高
内容的提问来源于stack exchange,提问作者Manu
相关产品推荐
相关产品推荐

