0%

第一阶段总结

rust和之前学过的语言有很多的不同。
5.2终于写完了rustlings的110道题目,学习了Rust 的基本语法、所有权系统、生命周期、 borrowing、traits、结构体、枚举、错误处理等多种核心概念。让我对rust有了初步的认识。在接下来的学习中从不断的使用Rust来精进对rust的理解。
第一阶段的训练营不仅是一次知识的洗礼,更是对自我挑战和成长的见证。期待在接下来的训练中取得更大的进步。

Axsl666-2023秋季OS训练营第二阶段总结

首先感谢learningOS社区的所有贡献者。前几次训练营因为错过报名时间而未能参加,终于在2023秋季参与到了本次训练营活动。

实验一内容总结

多任务系统的简单实现

  • 扩展 TaskControlBlock
    • start_time
    • started
    • syscall_times
  • 设计 TaskManager 的公共接口
    • add_syscall_times
    • get_current_task_info
  • 在相应函数中更新 TCB 数据, 记录开始时间:
    • run_first_task
    • run_next_task
  • 在系统调用处理函数中调用 add_syscall_times 更新 TCB 中的记录
  • 完成 sys_task_info 系统调用
    • 主要是调用 get_current_task_info 并返回 TaskInfo

实验二内容总结

系统开启虚拟地址空间

重写 sys_get_time 和 sys_task_info

  • 在内存管理中增加 translated_mut_ptr 函数,实现进程用户地址空间中的指针到可变引用的转换
  • 其余类似 ch3 中的操作

mmap 和 munmap 匿名映射

  • 内存管理接口
    • delete_frame_area
  • 任务管理接口
    • mmap:调用insert_framed_area增加映射区域
    • munmap:调用delete_frame_area删除映射区域
  • 系统调用的实现
    • 合法性检验
    • 调用任务管理接口 mmap 和 munmap

实验三内容总结

实现进程管理相关系统调用

实现系统调用 spawn

  • 扩展 Task 公共接口
    • spawn
      • MemorySet::from_elf 新建地址空间,用户栈,程序入口点
      • 分配 pid 与内核栈
      • 建立 TCB
      • 加入父进程的子进程链表
      • 准备 TrapContext
      • 返回新子进程的TCB
  • 完成系统调用功能
    • sys_spawn

实现 stride 调度算法

  • 扩展 TCB
    • stride
    • priority
  • 扩展 Task 公共接口
    • set_priority
  • 修改 TaskManager 调度算法
    • fetch 修改为 stride 调度算法
  • 完成系统调用功能
    • sys_set_priority 调用 set_priority

实验四内容总结

实现几个文件系统相关系统调用

sys_linkat

  • 给 File trait 增加 fstat 接口
  • 扩展 efs 中 DiskInode 接口
    • get_inode_id: get_disk_inode_pos的逆过程
  • 在 vfs 中 Inode 增加接口
    • create_link
      • 新建目录项,(new_name, old_inode_id)
  • 完成系统调用 sys_linkat

sys_unlinkat

  • 给 File trait 增加 fstat 接口
  • 扩展 efs 中 DiskInode 接口
    • get_inode_id: get_disk_inode_pos的逆过程
  • 在 vfs 中 Inode 增加接口
    • delete_link
      • 遍历目录下所有目录项,找到与对应文件名相同的inode
      • 删除(清空)对应目录项
  • 完成系统调用 sys_unlinkat

sys_stat

  • 给 File trait 增加 fstat 接口
  • 扩展 efs 中 DiskInode 接口
    • get_inode_id: get_disk_inode_pos的逆过程
  • 在 vfs 中 Inode 增加接口
    • inode_id: 实现获取自身 inode id
    • isdir:判读是 inode 否为目录
    • linknum: 获取 root inode 下的某一个 inode id 对应的硬链接数量
  • 完成系统调用 sys_stat

实验五内容总结

本节主要几种同步原语与及其内核实现。

  • 加入死锁检测机制,实现银行家算法。
  • 扩展 PCB 和 TCB
    • 可利用资源向量 分配矩阵 需求矩阵
  • 数据更新
    • 相关系统调用时进行更新数据
  • 检测算法
    • 获取资源前进行死锁检测

Rustlings 练习总结

作为一名前端全栈开发者,刚开始学习Rust时,给我的感觉是没想象中的难度那么高,学起来还挺轻松…
然而,还是太年轻了,当我开始真的用起来之后,我发现,编译器成为了我前进的“恶梦”,它无时无刻不在教我做人,总是会在不经意间鞭挞我:“你,还很菜呢!”
所以,慢慢的,我开始放弃了保守的学习方式:“先将文档中的内容都大致学会,并记下来”,它让我一直停留在学习的舒适区,对学习Rust来说是很低效的。
Rustlings 其实就是一种很好的学习语言的方式,通过大量的几乎全覆盖式的Rust练习,在练习中不断遇到问题,并解决问题,就像打怪升级,心理上会不断的得到激励感,并不断的做下去。
通过Rustlings的110道题目的练习,其实也让我意识到了,自己以为的会使用Rust了,只是井底之蛙吧了。
练习的内容虽然都在文档中,只看文档学习的化,其实有时候会忽略这些知识的真实用途是什么,也就无法在实际项目中灵活的去使用了。
通过这段时间的练习,不一定让我在Rust的熟练成都有很大的提升,但是让我看到了一个Rust用法的大纲,这已经是一个很好的开始了。
希望在接下来的开发里,不断精进对Rust使用,当然,也不能只专注在语法本身,对操作系统本身知识的学习,会更重要,非常期待!


title: 2024春夏季开源操作系统训练营第一阶段总结报告-fengtdi
date: 2024-04-24 21:38:58
tags:
- author:zlh20040308


2024春夏季开源操作系统训练营第一阶段总结报告

前言

了解到这个训练营源自一次机缘巧合,刚学完操作系统的鄙人在b站刷课时无意刷到了前训练营的导学部分,并在评论区看到了up主留下的链接,点进去一看正好都是我很感兴趣的方向,而且学习资源和github页面都整理得很完善,于是果断加入了

Rust编程基础

初探

第一阶段的的主要任务是学习Rust语言,刚接触这门语言时候的第一感觉就是概念十分的多,有些概念甚至看起来匪夷所思,如生命周期标注,我十分不理解为什么Rust要这么设计,但是秉持着能跑就行的原则,还是硬着头皮和编译器作斗争

初窥门径

带着以上这些问题,我找到了斯坦福大学CS110L这门课,这门课并不是教学生如何进行Rust编程,而是希望通过Rust的视角反映出当今两种主流内存分配机制——手动管理(malloc&free)和垃圾回收(GC)——的不足,在其三节课就主要讨论了它们所会遇到的问题:

  • 手动管理(C/C++)

    C/C++的类型系统对内存所有权的表达能力是十分有限的,以至于工程师在设计函数接口时会显得十分臃肿,还必须附上大量的注释来告知调用者去担负起管理内存的责任,也就是说内存的管理取决于程序员的自觉性,这就导致程序员经常会忘记之前申请过释放内存,而且随着工程的不断壮大,这种错误会不可避免地发生

  • 垃圾回收(Java)

    Java通过某种类似于引用计数的方式来自动回收内存,但这种设计会带来性能上的损耗(回收机制过于复杂)

而Rust便带来了属于它的第三种方案,那就是所有权机制,在这种机制下,内存管理会变得高效且安全,这得益于它强大的静态检测机制,能够在编译时期就规避掉很多内存泄露的隐患

但这也是有代价的,既然要求在编译时期就能发现错误,那么Rust编译器就会要求程序员在编码时附带足够多的信息供它推断,也就出现了类似于生命周期标注这些语法

牛刀小试

在初步过完几轮Rust基础并完成了rustlings之后,便开始着手用Rust复刻了一些之前写过的小项目(当然,还有那令Rust新手望而生畏的链表),在这段过程中越发能感受到Rust的一些设计理念在影响着我的编码习惯,也引起了我对与内存安全的思考

总结

在经历了这一阶段的学习后,虽然我到现在也不认为我是一个Rust程序员,但是也多多少少能用Rust去进行一些有效编码了

十分感谢第一阶段中为我答疑解惑的老师和同学,同时更要感谢开源操作系统训练营提供了这么一个平台把大家聚集在了一起,我十分喜欢这里的学习氛围,大家一起交流着学习上的疑惑并提出自己的见解,这开源的理念也使我收益颇丰

第一阶段练习总结

作为一名Cpper,我之前对Rust的了解可以说是毫无了解,这次受到朋友的邀请,第一次接触Rust,刚开始以为就是像C一样的过程语言。然而,当我真正开始深入学习和使用Rust时,我发现它远比我预想的要有趣和富有挑战性。特别是在进行Rustlings练习的过程中,我收获颇丰,也深刻体会到了Rust语言的强大和魅力。

Rustlings是一个设计精良的Rust语言练习项目,通过一系列由简到难的练习题,帮助开发者逐步掌握Rust的语法和特性。在练习的过程中,我遇到了许多看似简单但实则深奥的问题,这些问题让我不断思考和探索,也让我对Rust有了更深入的理解。

通过Rustlings的练习,我只能感叹面向编译器编程的魅力。

此外,Rustlings的练习还让我认识到了自己在编程思维方面的不足总的来说,Rustlings练习是我学习Rust过程中的一个重要环节。它不仅让我掌握了Rust的基本语法和特性,还锻炼了我的编程思维和解决问题的能力。我相信,在未来的学习和工作中,我会继续利用Rustlings等资源来深化对Rust的理解和应用,并不断提升自己的编程水平。同时,我也期待在未来的项目中能够充分发挥Rust的优势,写出更加健壮、高效的程序。

总结

这是我(plus7wist)在 Os-Camp 2024 的第一阶段的总结。

构建系统

我有一定的 Rust 基础,大概几年前也做过一次 rustlings 的练习。但这次练习里有包含 build script 的部分,我印象里从前那次是没有做过的。

Rust 的 build script 从它的环境变量获取包的信息,将要写出的设置写到标准输出。这很好地完成了一种插件设计。

进程之间通信的基本方式有如下一些:

  1. 命令行参数。
  2. 环境变量。
  3. 共享内存。
  4. 文件:
    1. 标准输入和输出。
    2. 命名管道或者其他设备文件。
    3. 网络。

这其中使用环境变量是最直接简单的。如果传递给插件系统的数据并不复杂,那么这种做法就是最好的。它不需要插件程序要做出很多的解析。

可以从几个方面来评判这些方式。

  1. 数据的复杂性。传递给进程的数据越复杂,就越需要某些协议,因此接收放需要解析这种协议。基于文件的方案需要的解析往往最复杂,命令行参数次之,环境变量最简单。

  2. 可靠性。基于文件的消息传递都要处理 IO 错误,这往往都是很复杂的。而获取命令行参数和环境变量则少有错误。

  3. 一次和多次。如果要向插件随着时序多次传递数据,命令行参数和环境变量都不合适了。这种情况选择文件,特别是标准输入文件是最常见的。

  4. 通信效率。仅在效率真的非常重要的场景,人们才会考虑共享内存。

插件系统,特别是 Rust 的构建系统需要的插件,并不需要多次通信,输入数据也不复杂,和插件通信也并不是效率瓶颈,因此环境变量输入确实非常合适。

而 Language Server 这样的软件设计上则采取标准输入和输出来通信,从上面的分析来看,这也是很合适的。

最后通过共享内存通信的软件体系,一般会使用某种数据分发服务(DDS)来隐藏解析过程。

算法

OS-Camp 的 rustlings 修改版本上增加了一些算法题目。显然它们的质量不高,只是作为一种实现算法的示例而已。

第一阶段总结

我了解到开源操作系统的训练营已经是4月底,我对操作系统非常感兴趣,但是苦于没有可以练手的项目,于是毫不犹豫地报名了这次训练营。我主要通过阅读rust语言圣经,看训练营的rust视频教学了解rust的基本语法,然后完成rustlings来查漏补缺。rustlings的前100题是rust基本语法的检测,但有时也会涉及参考书籍中没有出现的内容。在遇到难以解决的问题时,我会通过hint指令查找是否有有用的提示,或者去看详细的英文文档,基本都能解决问题。最后10题需要用rust实现一些基本数据结构和算法,在自己的实现过程中能体会到rust和其他语言差距很大,有更多的限制,想要习惯rust的写法还需要多写代码。

未来计划

虽然完成了rustlings的110道题,但是只是rust语言最基础的内容。想要设计一个标准的rust项目,实现一个成熟的rust项目还有很大的提升空间。我计划抓紧时间继续学习rust和操作系统,及时赶上后续的milestone。

初次认真学习rust每一个点

通过某些渠道,第一次了解到操作系统训练营,以前我也有用rust写过一些内容,但严格来说这是我的第一次正式学习rust。学习了很多的内容,了解到了闭包,函数式编程,拓展了我的知识面,我第一次见到结构如此清晰的语言。

所有权的理解

众所周知,rust很贪。所有权是其中的灵魂。我认为,其本质就是“作茧自缚”,减少了许多东西,又为方便开发与调试添加了许多东西。这些设计减少了许多的错误。所以简单的把所有权当作单线程的脑子就行,不要给它过多的行为。

错误处理中的Option Result

  • Option 用于表达可能存在或者不存在的值,它有两种可能的状态:Some(值) 和 None。当你不确定一个值是否存在时,可以使用 Option 来处理这种情况。

  • Result 则用于表达可能的操作成功或失败的结果,它有两种可能的状态:Ok(值) 和 Err(错误)。当你需要处理可能出现错误的情况时,可以使用 Result 来处理这种情况。

令人耳目一新的枚举类型 match

在 Rust 中,枚举类型是一种非常强大的数据结构,它可以用来表达一组相关的值。而使用 match 关键字可以让我们更加灵活地处理枚举类型的值,使得代码更加清晰易懂。

match 表达式可以用来匹配枚举类型的不同变体,并根据不同的情况执行相应的代码逻辑。这种模式匹配的方式让代码的逻辑结构清晰明了,同时也增强了代码的可读性和可维护性。

我的收获

通过学习 Rust,我收获了很多。不仅仅是语言本身的特性和语法,更重要的是 Rust 给我带来的编程思维方式的转变。在学习 Rust 的过程中,我更加注重代码的安全性和可靠性,学会了如何利用 Rust 的各种特性来编写更加健壮的程序。

另外,通过与社区的交流和分享,我还了解到了很多其他开发者的经验和见解,这也让我受益匪浅。总的来说,学习 Rust 是一次非常有意义的经历,我相信在将来的工作和项目中,我会继续运用 Rust 的知识和思想,为我的编程生涯注入新的活力和动力。

第一阶段学习总结

作为一名Cpper,学习Rust的过程属实有点难受,在使用习惯上存在很大的差别,往常习惯的写法在Rust中都不能满足语言规范。

通过学习之后我也体会到Rust的优秀之处:抛弃手动管理和GC,用更“高效”的所有权机制来处理引用。

不过这也天生的给Rust带来了一些劣势:所有权机制本质上是谁管理谁的问题,但是一个链表中的所有节点都是 peers 是平等的,前一个节点牺牲了不会影响后面的节点;所有权机制必然导致数据存在“从属”关系,这让链表的表示比较困难,必须使用一些unsafe代码

另外也算是认识了一下函数式编程的魅力,Rust提供了大量操作的抽象,熟练的运用后能很好的节省代码量(当然随之而来的是对我心智负担的增加)

后续我会继续学习,整理一下常用函数,让使用更加流畅