进程模块概述

简介

这篇文档简要记录了进程模块的设计思路,具体实现细节见该文件夹下各个文件

导航

设计

概要

本模块将进程称为 Task,并不区分线程与进程。我们假定:

线程是共享某些资源的 Task

进程的表示

Task 结构

Task 结构体表示一个程序及其运行所需的资源和信息。其主要职责是管理与任务相关的资源和调度信息。

#![allow(unused)]
fn main() {
pub struct Task {
    /// 中断上下文。指向任务内核栈上的 TrapFrame,仅在任务被中断时有效。
    pub trap_frame_ptr: AtomicPtr<TrapFrame>,
    
    /// 任务的内存空间。对于内核任务,该字段为 None。
    pub memory_space: Option<Arc<MemorySpace>>,
    
    // TODO: 存放任务持有的文件句柄
    // ......
}
}

资源管理

任务执行需要以下资源:

  1. CPU:用于计算,通常包含寄存器、ALU、控制单元等。
  2. 内存:用于存储数据(包括代码)。内存通过 MMU 被虚拟化成虚拟内存。
  3. 外部设备:用于与外部世界交互,抽象为文件(通过 VFS 访问)。

调度相关信息

Task 还需要包含调度器所需的关键信息,以便任务切换和调度。关键字段包括:

  • context:最小上下文,包含任务切换时需要恢复的寄存器(例如 spra 等)。

  • state:任务当前的状态,可能的值包括:

    • Running:任务正在执行。
    • Interruptible:任务可以被中断。
    • Uninterruptible:任务无法被中断。
    • Stopped:任务已经终止。
  • priority:任务的优先级,供调度器参考。

  • preempt_count:抢占计数,防止在关键区域内被抢占。

  • kstack_base:内核栈的基地址,供内核线程或陷阱处理使用。

  • trap_frame_ptr:指向当前任务内核栈上的 TrapFrame,用于处理中断或从陷阱返回。

进程的生命周期

Task 的生命周期从创建到销毁,涉及多个状态转换,常见状态包括:创建、运行、就绪、阻塞、退出。

1. 创建(Created)

  • 通过 ktask_createutask_create 创建。
  • 分配内核栈、TrapFrame,并初始化 contexttrap_frame
  • 初始状态为 Running

2. 运行(Running)

  • 当前 CPU 正在执行该任务。
  • 状态保持为 Running

3. 就绪(Runnable / Ready)

  • 任务已准备好等待 CPU 调度。
  • 被放入就绪队列,等待调度器选择。
  • 状态为 Ready

4. 睡眠(Blocked)

  • 任务因等待某些资源(如 I/O、锁、信号等)被阻塞。

  • 阻塞状态分为:

    • Interruptible:任务可以在等待期间被中断。
    • Uninterruptible:任务无法被中断。
  • 任务将加入 waitqueue,在满足条件时被唤醒。

5. 退出(Stopped / Dead)

  • 任务执行完毕,进入退出状态。
  • 设置 exit_codereturn_value,并开始资源回收(如内存、文件句柄等)。
  • 状态为 StoppedDead

典型 API 操作

以下是任务管理中的常用 API 操作:

  • create / spawn:创建并初始化 Task,分配必要资源。
  • schedule / yield:让出 CPU,触发调度操作。
  • sleep / wake_up:使任务进入阻塞状态或从阻塞中唤醒,通常通过 waitqueue 和锁模块实现。
  • exit / terminate:终止任务并回收相关资源。
  • join / waitpid:等待子任务退出,并获取其 exit_codereturn_value

进程状态转换图

 +-------------------+       +-------------------+
 |     Created       |-----> |      Running      |
 +-------------------+       +-------------------+
                                |
                                v
                       +-------------------+
                       |      Ready        |
                       +-------------------+
                                |
                                v
                       +-------------------+
                       |     Blocked       |
                       +-------------------+
                                |
                                v
                       +-------------------+
                       |      Stopped      |
                       +-------------------+

总结

  • Task 是程序的基本运行单元,负责管理进程的资源和调度。
  • 任务的生命周期经历创建、运行、就绪、睡眠、退出五个状态。
  • 提供了一些核心的 API 来操作任务,支持调度、阻塞、退出等功能。