linux - 在 Linux 中使用计时器停止内核线程

标签 linux timer kernel linux-device-driver

我试图通过在定时器调用的函数中调用 kthread_stop() 来停止内核线程。当我将此模块加载到内核中时,kthread 在定时器中提到的指定时间后启动和停止,但它的在日志中给出一些错误信息。

谁能帮我解决这个问题,因为我是内核线程编程的新手。这是我的代码

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/timer.h>
#include <linux/kthread.h>
#include <linux/sched.h>
MODULE_LICENSE("GPL");
struct task_struct *task;
static struct timer_list my_timer;
int thread_function(void *data) {
    printk(KERN_ALERT"IN THREAD FUNCTION");
    while(!kthread_should_stop()){
    schedule();
    }
printk(KERN_ALERT"after schedule\n");
return 1;
}

void my_timer_callback( unsigned long data ){
printk( "my_timer_callback called (%ld).\n", jiffies );
printk(KERN_ALERT"THREAD STOPPED\n");
kthread_stop(task);
}

int init_module( void ){
    int ret;
    printk("Timer module installing\n");

    //my_timer.function, my_timer.data
    setup_timer( &my_timer, my_timer_callback, 0 );

    printk( "Starting timer to fire in 2000ms (%ld)\n", jiffies );
    ret = mod_timer( &my_timer, jiffies + msecs_to_jiffies(2000) );
    if (ret) printk("Error in mod_timer\n");
    printk(KERN_INFO"-------------------- THREAD START------------------------");

    task = kthread_run(thread_function,NULL,"kerneltthread");
    printk(KERN_ALERT"Kernel Thread Name: %s\n",task->comm);

    return 0;
}

void cleanup_module( void ){
    int ret;

    ret = del_timer( &my_timer );
    if (ret) printk("The timer is still in use...\n");

    printk("Timer module uninstalling\n");

    return;
}

 MODULE_LICENSE("GPL");

这是日志中的输出信息

Aug  5 16:35:31 brao kernel: Timer module installing
Aug  5 16:35:31 brao kernel: Starting timer to fire in 2000ms (4299209850)
Aug  5 16:35:31 brao kernel: -------------------- THREAD             START------------------------
Aug  5 16:35:31 brao kernel: Kernel Thread Name: kerneltthread
Aug  5 16:35:31 brao kernel: IN THREAD FUNCTION
Aug  5 16:35:33 brao kernel: my_timer_callback called (4299211856).
Aug  5 16:35:33 brao kernel: THREAD STOPPED
Aug  5 16:35:33 brao kernel: BUG: scheduling while atomic: swapper/3/0/0x10000100
Aug  5 16:35:33 brao kernel: after schedule

最佳答案

Timer 的功能 在 softirq 上下文中执行,因此它不应该休眠。但是您的 my_timer_callback 调用了 kthread_stop 函数,该函数等待直到 kthread 完成,即休眠。

因此,scheduling while atomic BUG 出现了:函数休眠而它不应该这样做,因为原子上下文。

关于linux - 在 Linux 中使用计时器停止内核线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31831381/

相关文章:

Objective-C:在 SpriteKit 中向计时器添加 10 秒

linux - 内核 oops - 页面保护错误

python - Jupyter 实验室和笔记本问题 : Kernel Error

assembly - Kernel.c 没有执行完整的代码 [OS from scratch]

python - 当我尝试列出 FTP 服务器时得到 "ConnectionRefusedError"

linux - 如何在不更改扩展名的情况下将许多文件(通过 glob 找到)从小写重命名为大写?

java - 每 X 秒运行一次代码 (Java)

c++ - 初始化后无法更改 C++ 变量

linux - 如何在编辑器中传输程序输出?

timer - 如何按需删除和重启 esp32 arduino(步进电机 Controller 应用程序)的硬件定时器(用于中断)