admin管理员组文章数量:1588196
这是 os summer of code 2020 项目每日记录的一部分:
每日记录github地址(包含根据实验指导实现的每个阶段的代码):https://github/yunwei37/os-summer-of-code-daily
这里参考的是rCore tutorial的第三版:https://github/rcore-os/rCore-Tutorial
lab4 学习报告
lab4 涉及:
- 线程和进程的概念以及运行状态的表示
- 线程的切换
- 对 CPU 进行抽象在上面完成对线程的调度
lab4 的代码将会在 lab3 完成的代码上面继续进行改动;
线程和进程
- 程序(Program):从源代码经过编译器一系列处理(编译、链接、优化等)得到的可执行文件
- 进程(Process):正在运行并使用计算机资源的程序
- 线程 (Thread) :借助 CPU 和栈的执行流
首先,进程得到了操作系统提供的资源:程序的代码、数据段被加载到内存中,程序所需的虚拟内存空间被真正构建出来。同时操作系统还给进程分配了程序所要求的各种其他资源,如我们上面几个章节中提到过的页表、文件的资源。一个进程可以有多个线程,也可以如传统进程一样只有一个线程。
- 资源的分配单位:进程
- 执行的调度单位:线程
线程的表示
在这里我们提供一种基础的实现,每个线程会包括:
- 线程 ID
- 运行栈
- 线程执行上下文 ( Context 类型 )
- 所属进程的记号
- 内核栈
新建一个 process 文件夹:
先添加一个 mod.rs:
mod config;
mod kernel_stack;
#[allow(clippy::module_inception)]
mod process;
mod processor;
mod thread;
use crate::interrupt::*;
use crate::memory::*;
use alloc::{sync::Arc, vec, vec::Vec};
use spin::{Mutex, RwLock};
pub use config::*;
pub use kernel_stack::KERNEL_STACK;
pub use process::Process;
pub use processor::PROCESSOR;
pub use thread::Thread;
再添加
os/src/process/thread.rs:
包含线程的数据结构:
//! 线程 [`Thread`]
use super::*;
use crate::fs::*;
use core::hash::{Hash, Hasher};
/// 线程 ID 使用 `isize`,可以用负数表示错误
pub type ThreadID = isize;
static mut THREAD_COUNTER: ThreadID = 0;
/// 线程的信息
pub struct Thread {
/// 线程 ID
pub id: ThreadID,
/// 线程的栈
pub stack: Range<VirtualAddress>,
/// 所属的进程
pub process: Arc<RwLock<Process>>,
/// 用 `Mutex` 包装一些可变的变量
pub inner: Mutex<ThreadInner>,
}
/// 线程中需要可变的部分
pub struct ThreadInner {
/// 线程执行上下文
///
/// 当且仅当线程被暂停执行时,`context` 为 `Some`
pub context: Option<Context>,
/// 是否进入休眠
pub sleeping: bool,
/// 是否已经结束
pub dead: bool,
/// 打开的文件
pub descriptors: Vec<Arc<dyn INode>>,
}
进程的表示
进程只需要维护页面映射,并且存储一点额外信息:
- 用户态标识:我们会在后面进行区分内核态线程和用户态线程。
- 访存空间 MemorySet:进程中的线程会共享同一个页表,即可以访问的虚拟内存空间(简称:访存空间)。
创建:os/src/process/process.rs
进程的数据结构:
//! 进程 [`Process`]
use super::*;
use xmas_elf::ElfFile;
/// 进程的信息
pub struct Process {
/// 是否属于用户态
pub is_user: bool,
/// 进程中的线程公用页表 / 内存映射
pub memory_set: MemorySet,
}
实际上这部分有一些代码和第五章的部分内容交织在了一起。
线程的创建
第一个目标就是创建一个线程并且让他运行起来。
一个线程要开始运行,需要这些准备工作:
- 建立页表映射,需要包括以下映射空间:
- 线程所执行的一段指令
- 线程执行栈
- 操作系统的部分内存空间
- 设置起始执行的地址
- 初始化各种寄存器,比如 sp
- 可选:设置一些执行参数(例如 argc 和 argv等 )
思考:为什么线程即便与操作系统无关,也需要在内存中映射操作系统的内存空间呢?
- 简单来说,需要使用内核来处理中断。
- 我们会为每个进程的页表映
版权声明:本文标题:rust写操作系统 rCore tutorial 学习笔记:实验指导四 进程与线程 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dongtai/1728025859a1142662.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论