内核线程看守者:创建一个周期性打印状态的内核线程

内核模块 内核线程 打印状态 休眠10秒 循环执行

项目概述

在本项目中,我们将创建一个Linux内核模块,该模块会启动一个内核线程。这个线程将作为一个"看守者",每隔10秒打印一次自己的状态信息,包括线程ID、运行状态等。

提示: 内核线程是Linux内核中在后台运行的特殊进程,没有用户空间,常用于执行内核中的后台任务。

关键技术点

技术点 说明
内核线程创建 使用kthread_create()或kthread_run()函数创建内核线程
线程函数编写 实现线程的主要逻辑,包括循环和休眠
延时机制 使用msleep()或ssleep()实现线程休眠
状态信息获取 获取并打印线程的ID、名称、状态等信息

实现步骤

  1. 包含必要的头文件
  2. 定义线程函数,实现周期性打印逻辑
  3. 在模块初始化函数中创建并唤醒线程
  4. 在模块退出函数中停止并清理线程
  5. 编写Makefile文件
  6. 编译、加载和测试模块

代码实现

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/kthread.h>
#include <linux/delay.h>

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("内核线程看守者示例");

static struct task_struct *watchdog_thread;

// 线程函数
static int watchdog_thread_func(void *data)
{
    while (!kthread_should_stop()) {
        // 打印线程信息
        printk(KERN_INFO "看门狗线程[%s] ID:%d 正在运行\n", 
               current->comm, current->pid);
        
        // 休眠10秒
        ssleep(10);
    }
    
    printk(KERN_INFO "看门狗线程退出\n");
    return 0;
}

// 模块初始化函数
static int __init watchdog_init(void)
{
    printk(KERN_INFO "初始化看门狗模块\n");
    
    // 创建内核线程
    watchdog_thread = kthread_create(watchdog_thread_func, NULL, "my_watchdog");
    if (IS_ERR(watchdog_thread)) {
        printk(KERN_ERR "无法创建看门狗线程\n");
        return PTR_ERR(watchdog_thread);
    }
    
    // 唤醒线程
    wake_up_process(watchdog_thread);
    printk(KERN_INFO "看门狗线程已启动\n");
    
    return 0;
}

// 模块退出函数
static void __exit watchdog_exit(void)
{
    printk(KERN_INFO "卸载看门狗模块\n");
    
    // 停止线程
    if (watchdog_thread) {
        kthread_stop(watchdog_thread);
        printk(KERN_INFO "看门狗线程已停止\n");
    }
}

module_init(watchdog_init);
module_exit(watchdog_exit);

Makefile示例

obj-m := watchdog.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)

all:
    $(MAKE) -C $(KDIR) M=$(PWD) modules

clean:
    $(MAKE) -C $(KDIR) M=$(PWD) clean

测试方法

  1. 使用make命令编译模块
  2. 使用sudo insmod watchdog.ko加载模块
  3. 使用dmesg命令查看内核日志,确认线程已启动
  4. 等待10秒,再次查看日志,确认周期性输出
  5. 使用sudo rmmod watchdog卸载模块

注意事项

内核线程生命周期 创建 运行 休眠 停止 kthread_create wake_up_process ssleep(10) kthread_stop

扩展思考