流程

线程流程

线程一

执行thread1_func()

  1. 遍历进程(for_each_process宏,用kthread_should_stop()判断是否需要直接返回,终止线程)

    1. 创建节点为节点分配内存(kmalloc

    2. 将进程信息(pidcomm)写入节点指向的结构体(进程名commstrncpy()拷贝)

    3. 获取自旋锁(spin_lock()),用尾插法将节点插入链表(list_add_tail宏),释放自旋锁(spin_unlock()),完成对链表的互斥访问

  2. 调用complete()指示线程一已结束

线程二

执行thread2_func()

  1. 循环(用kthread_should_stop()判断是否需要直接返回,终止线程)

    1. 获取自旋锁(spin_lock()
    2. 判断内核链表是否为空(list_empty宏)

      • 非空

        1. 取头节点(list_first_entry宏),将该节点摘出链表(list_del()
        2. 释放自旋锁(spin_unlock()
        3. 打印节点所指结构体存储的信息(printk()
        4. 释放节点内存(kfree()
      • 为空
        1. 释放自旋锁(spin_unlock()
        2. 判断线程一是否已经结束(completion_done()),如果结束跳出循环(否则即使已完成任务,在rmmod前仍会一直占用CPU资源,内核爆炸警告!)

模块流程

内核模块初始化

module_init宏以kernel_module_init()为入口点,在执行insmod命令时调用

  1. 初始化自旋锁和内核链表表头(spin_lock_init宏、INIT_LIST_HEAD宏)
  2. 创建并唤醒执行thread1_func()thread2_func()的内核线程(kthread_run宏),并进行错误处理

内核模块卸载(module_exit宏,执行rmmod命令时调用)

module_exit宏以kernel_module_exit()为退出函数,在执行rmmod命令时调用

  1. 如果线程一、二仍未结束(状态为TASK_RUNNING),通知其结束(kthread_stop())(注意不能对已结束线程这样做,ub警告!)
  2. 遍历内核链表(list_for_each_entry_safe宏)
    1. 摘出链表节点(list_del()
    2. 释放其内存(kfree()