You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

内核模块工作线程调用kthread_stop后无法停止的问题排查

问题分析与解决方向

你的核心问题在于:线程被阻塞在down_interruptible(&mutex)时,kthread_stop()无法让线程主动退出——因为线程根本没机会执行kthread_should_stop()检查,而kthread_stop()不会主动发送信号中断down_interruptible的阻塞。

具体原因拆解

  1. 模块初始化时,my_module_init()调用down(&mutex)持有了信号量,导致后续线程启动后,down_interruptible(&mutex)一直阻塞,无法进入循环体检查停止标志。
  2. kthread_stop()的工作逻辑是:设置线程的停止标记,唤醒线程(仅针对kthread内部的等待队列),然后等待线程主动退出。但你的线程卡在信号量的等待队列里,kthread_stop()无法唤醒它,也不会发送信号触发down_interruptible返回-EINTR。

修复方案

方案1:先释放信号量,再调用kthread_stop

在模块退出函数中,先释放持有的信号量,让线程能从down_interruptible返回,进而检查停止标志退出:

修改后的退出函数:

static void __exit my_module_exit(void) 
{
    printk(KERN_INFO "stopping sample thread\n");
    up(&mutex); // 先释放信号量,让线程从阻塞中恢复
    kthread_stop(sample_thread_handle);
    printk(KERN_INFO "after stopping consumer thread\n");   
    printk(KERN_INFO "Goodbye, world!\n");
}

方案2:优化线程循环逻辑(可选)

确保线程在每次尝试获取锁失败(或被中断)后,都能重新检查停止标志:

int sample_thread(void *arg)
{
   printk(KERN_INFO "Starting Thread...");
   while(!kthread_should_stop())
   {
      if(down_interruptible(&mutex)) {
          // 如果被中断,直接回到循环开头检查停止标志
          continue;
      }
      // 这里可以添加获取锁后的业务逻辑
      up(&mutex); // 记得用完锁释放
   }
   printk(KERN_INFO "Leaving Thread...");
   return 0;
}

额外注意事项

  • 内核线程中使用信号量时,必须保证锁的释放逻辑完整,避免出现永久阻塞。
  • kthread_stop()必须配合线程内部的kthread_should_stop()检查使用,线程需要有机会周期性检查这个标志才能正常退出。

内容的提问来源于stack exchange,提问作者Rob Goodwin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 00:47:13