news 2026/9/28 11:58:07

操作系统导论(OSTEP)笔记答案代码:从解压到运行模拟器的避坑全攻略

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
操作系统导论(OSTEP)笔记答案代码:从解压到运行模拟器的避坑全攻略

简介:这是一份以《操作系统导论》(OSTEP)为核心的完整学习资料包,面向计算机专业学生、考研复习者及自学操作系统的读者,涵盖进程管理、内存管理、文件系统、I/O设备控制等核心专题,并配有课后习题答案与可运行的实验代码,帮助解决理论学习与动手实践脱节的问题。压缩包内共294个文件,以97个Markdown笔记、71个C源码、33个Python脚本、19个头文件、13个Makefile为主体,另有汇编程序、README说明与少量图片,整体约902KB,目录层次清晰,便于按模块快速定位。该资源已有82人学习下载,适合计算机专业学生作为课堂辅助,考研准备者用于系统梳理,也适合业余自学者按章节推进,或针对薄弱环节单独查阅。针对进程调度、虚拟内存、同步互斥、文件系统设计等难点,既有结构化笔记,也有可直接运行的调度模拟、内存分配与文件系统操作代码,配合习题答案验证思路,能显著提高课后练习与实验效率,尤其适合在课程设计或实验报告中参考。

1. 操作系统导论(ostep)笔记_课后习题答案_附加代码.zip:一个打包成zip的操作系统学习闭环

你手上这个《操作系统导论(ostep)笔记_课后习题答案_附加代码.zip》,并不是让你跳过学习的捷径包。我第一次拿到时也以为笔记省了整理、答案省了推导。真正打开跑了一遍才发现,值钱的部分反而是最后那个“附加代码”——OSTEP的课后作业几乎都围绕这些小模拟器和示例程序设计,没有它们,笔记里的调度算法、并发同步、页面置换永远停留在纸面。我下面顺着这个zip包的三块内容往下拆:怎么把笔记读薄、怎么用答案做验证、怎么把附加代码在Linux操作系统上跑通,以及我踩过的坑。适合正在学操作系统课程、期末复习或转码补基础的人。

2. 拆开zip先别急着对答案:用ostep笔记把操作系统读薄

OSTEP 这套资料流传很广,但很多人拿到的是一堆没整理的散乱文件,目录层级乱得让人不想打开。我的建议是:解压后第一件事不是翻答案,而是先建立“笔记 -> 课后题 -> 附加代码”的对应关系。如果你一上来就对着答案看,最多半小时就会丢失目标,因为答案只能告诉你“是什么”,不能告诉你“为什么改一个参数结果就翻车”。

2.1 解压前先看zip内容清单:识别版本和缺文件的信号

最常见的错误是拿到zip立刻双击解压。我一般会先用unzip -l把清单列出来,因为OSTEP资料包流传的版本很多,有的整理者会把模拟器脚本漏掉,有的会把答案按章节拆开。先看清单能省掉后面一半的坑。

unzip -l "操作系统导论(ostep)笔记_课后习题答案_附加代码.zip" | head -80

unzip -l只读取压缩包的中央目录,不实际解压文件,所以执行很快。head -80限制输出行数,避免目录太长刷屏。这里有两个细节要注意:第一,zip 文件名里带括号和小写英文,在 bash 中必须用双引号包起来,否则(会被当成子 shell 语法;第二,观察输出的重点不是文件名本身,而是目录结构和文件后缀。

我会重点看三件事:第一层目录有没有notes/、answers/、code/或homework/这类清晰划分;文件后缀是否包含.py、.c,这代表了附加代码是否完整;有没有个别文件明显比其他文件小很多,例如scheduler.py只有几 KB 但目录里却没看到,那很可能是被精简掉了。如果一个资料包只有 PDF 笔记和答案,没有.py脚本,那它不是一个完整的 OSTEP 学习包,因为书里大量作业题都要求运行模拟器。

2.2 读笔记的正确姿势:按“虚拟化-并发-持久化”三条主线做勾联

OSTEP 原书不是教科书式写法,它用“三个简单片断”讲操作系统:虚拟化、并发、持久化。市面上的 OSTEP 笔记,多数是按原书章节提炼的要点、图表和代码片段。但笔记只是别人嚼过的内容,不能替代原书。我的做法是先读一章原书,再打开对应笔记,把笔记里每条要点对应到书里的一个故事或一个例子。

比如讲调度那一章,书里用顾客排队买咖啡的例子引入策略,笔记里如果只写“SJF == Shortest Job First”,没有用。你要能直接说出:当作业同时到达时,SJF 能最小化平均周转时间;当作业陆续到达时,SJF 可能让长作业饿死。再比如虚拟化章节里的地址翻译,笔记里画了两张页表,但真正需要理解的是“TLB 命中一次翻译,没命中就要走页表遍历”,这个流程用模拟器跑一次比背十遍笔记都管用。

我看笔记时会在旁边补三个记号:虚线框代表书中的例子,箭头指向对应机制,星号代表需要自己跑模拟器验证。这个习惯能让一份外部笔记变成自己的复习地图,也避免期末对着答案却想不起原理。如果你是准备考试,建议把笔记的每个章节标题都转成一句“我能干什么”,例如“我能用 FIFO 和 SJF 算平均周转时间”,而不是“这章讲调度”。

2.3 笔记和课后习题答案的对应关系:哪些是复习题,哪些是作业题

OSTEP 每章末尾有两种题:复习题和作业题。复习题是简答类,例如“上下文切换时硬件保存了什么,操作系统保存了什么”;作业题则要求你运行该章附带的模拟器,观察参数变化。常见资料包里的答案往往混在一起,如果不区分,会踩一个坑:你把复习题答案背得滚瓜烂熟,却不知道作业题的答案长什么样。复习题答案可以在笔记里直接用,作业题答案则必须配合命令复现。

主题核心章节示例常见作业形式笔记里该补什么
虚拟化进程、CPU调度、地址空间、页表运行 scheduler.py、paging-policy.py 改参数调度算法和页面置换算法的流程,以及每个参数对结果的影响
并发锁、条件变量、信号量编译运行 thread.c 等 C 程序临界区、死锁触发条件、锁的竞争开销
持久化文件系统、RAID、日志运行 fsck.py、raid.py 模拟器磁盘布局、RAID 级别容错计算

这个表格不是用来背的,而是用来检查资料包是否完整。如果一个章节对应的.py脚本缺失,你很难完成作业题。复习题可以靠笔记回答,但作业题必须靠代码跑出结果。答案的用途是给作业题提供一个基准输出,但你最好先自己算一遍,再让模拟器当裁判。这正是下一章要展开的操作。

3. 课后习题答案的几种正确用法:先自己算,再让模拟器当裁判

很多人拿答案当“黑匣子”,只看最终数字,却不关心数字怎么来的。OSTEP 的作业题和普通习题集不同,它给的是模拟器输入参数,不是固定题目,所以答案并不是唯一解释权,可复现的代码才是。这里我按自己用过三轮的经验,把答案的用法分成三个层次。

3.1 答案只是参照系:先自己推导再对答案,错题才长本事

以调度章节为例,作业题通常给你一组进程的到达时间和服务时间,让你计算 FIFO、SJF、RR 的平均周转时间或平均响应时间。如果你直接翻答案,只记住了那个数字,换一组负载又不会了。正确流程是这样的:

  1. 打开笔记或原书,确认公式。周转时间等于完成时间减到达时间;响应时间等于首次运行时间减到达时间。
  2. 用表格手算,或者用 Python 写一个小脚本算。
  3. 跑模拟器,加-c参数让模拟器打印计算结果。
  4. 拿自己的结果和答案对比。

如果一致,说明思路对;如果不一致,先别急着怀疑自己,答案也有可能是旧版模拟器算的。OSTEP 各版次会改作业题,模拟器也会更新,资料包里的答案经常是几年前的,数字对不上很正常。我见过最典型的例子是书里的作业题要求进程数量-j 3,但答案贴出来的表却是-j 5,明显是整理答案的人自己改过参数。这时候你按原题跑,永远对不上。

所以我把答案定位成“参照系”,不是“标准答案”。它能帮你确认章节重点,但真正长本事的是你在对答案之前做的那次推导。错题也只有在你先动过脑之后才有价值,直接背答案等于没做。

3.2 用一段Python复现“作业题”结果:以调度模拟器为例

我一直觉得,能用十行 Python 手算一道调度题,比拿着答案背十遍更有用。下面这段脚本模拟非抢占式 FIFO 调度,输入是一个进程列表,每个元素是“到达时间, 服务时间”:

# fifo_avg_turnaround.py # 输入:进程到达时间和服务时间列表 jobs = [(0, 100), (10, 10), (10, 10), (10, 10)] # (arrival, burst) time = 0 completion = [] for arrival, burst in jobs: if time < arrival: # 如果CPU空闲到该进程到达 time = arrival # 时钟跳转到到达时间 time += burst # 执行该进程 completion.append(time) # 记录完成时间 turnaround = [c - a for c, (a, _) in zip(completion, jobs)] print("完成时间:", completion) print("平均周转时间:", sum(turnaround) / len(turnaround))

这段代码的逻辑很直接:按作业列表顺序执行,如果当前 CPU 时间小于下一个进程的到达时间,说明 CPU 在空闲,就把时钟跳到到达时间。完成时间减去到达时间就是周转时间。输出的平均周转时间就是作业题要的那个数。

你可以修改jobs里的数字做不同实验,也可以把列表按服务时间排序来模拟 SJF。但这里有个坑:SJF 在进程同时到达时才生效,如果到达时间不同,简单排序不一定是真正的 SJF 结果。所以更可靠的方式是直接跑官方模拟器,在作业目录下执行:

python3 scheduler.py -p FIFO -l 0,100,10,10,10,10 -c

-p指定调度策略,-l后面的数字每两个一组,分别是到达时间和服务时间,-c让模拟器计算出统计结果。注意,如果没有-c,模拟器只画执行顺序图,不会打印平均周转时间。这就是答案背后真正的计算过程。

3.3 当答案和你算的不一致:按参数和随机种子逐行核对

我和不少同学交流过,发现“答案对不上”这种事十有八九是参数问题。最典型的是作业题里写-s 3 -j 5,你随手跑一个-s 1,结果当然不一样。OSTEP 模拟器的随机种子-s控制进程集合,种子不同,生成的作业表就不同。答案往往只对应题目给出的那个种子,换一个就面目全非。

排查时我会按这个顺序来:第一步,用python3 scheduler.py -h查看当前模拟器的参数名,确认-s、-j、-l、-c的定义和答案使用的方式一致。第二步,确认题目问的是平均周转时间还是平均响应时间,这两个指标在同一份输出里都会出现,答案可能只抄了其中一个。第三步,检查负载列表的顺序,同样是三个进程,FIFO 和 SJF 的顺序不同,结果就不同。第四步,如果题目用的是随机进程集合,必须固定随机种子再跑,不固定的话每次结果都不同。

如果以上都对不上,最终裁判是模拟器的-c输出,而不是答案文本。答案整理者和你用的模拟器版本不一样,这种情况在老旧资料包里太常见了。你要相信代码的可复现性,而不是某份无法考证的答案。这也提醒我:每次跑作业题时,把使用的命令、随机种子和关键输出都保留下来,免得以后回来看自己都不知道当时怎么算的。

4. 把附加代码在linux操作系统上跑通:scheduler.py与C示例的编译运行

附加代码是整套资料里最容易被浪费的部分。很多人以为它是可有可无的源码,实际上它是 OSTEP 作业的“命题载体”。如果你在 Windows 上直接双击.py文件,大概率只闪一下黑窗就没了。我推荐在 Linux 操作系统上跑,或者用虚拟机、WSL 装一个 Ubuntu,这样命令和书里完全一致,避免“我的环境不行”这类干扰。

4.1 附加代码的组成:python模拟器、C示例、shell工具

OSTEP 的附加代码可以分成两类。第一类是模拟器,通常是单个 Python 脚本,用来生成调度、分页、RAID 等场景。它们依赖很少,基本只用标准库,所以只要有一个 Python 解释器就能跑。第二类是书里讲解用到的短 C 程序,比如进程创建、多线程、锁和信号量,这些需要一个 C 编译器。

不同资料包的目录命名差别很大,有的叫homework/,有的叫ostep-code/,还有的直接把脚本和笔记放同一层。不要预设目录,先跑一条查找命令:

find . -name "*.py" -o -name "*.c" | sort | head -30

这条命令会在当前目录递归找出所有.py和.c文件,sort让输出有规律,head -30截断前三十行。看到文件列表之后,你就能判断附加代码的完整度。如果调度章节找不到对应的.py,说明资料包不完整,后续作业只能靠手算,学习效果大打折扣。

我在实际使用时会为这套资料单独建一个 Python 虚拟环境,不是因为这些脚本需要特定依赖,而是系统 Python 环境可能被改得很乱,用虚拟环境可以保证python3指向干净的解释器。这只是个习惯,不是必须步骤,但能少踩很多版本坑。

4.2 跑通第一个模拟器:scheduler.py 的启动命令与参数解读

我建议第一个跑通的是调度模拟器scheduler.py,因为它输出简单、参数直观,能立刻让你看到调度策略的区别。假设你已经找到脚本所在目录,执行:

cd <解压目录>/homework/scheduling python3 scheduler.py -p FIFO -l 0,100,10,10,10,10 -v -c

这里的<解压目录>要根据你的实际路径替换。命令中-p FIFO指定调度策略,-l后面是负载列表,每两个数字一组:到达时间、服务时间,所以0,100表示进程在时间 0 到达,需要运行 100;10,10表示进程在时间 10 到达,需要运行 10。-v打开详细输出,-c让模拟器计算并打印统计结果。

如果你看到的是 Python 语法报错,先别慌,下一章会说怎么处理。跑通之后,试着把-p FIFO改成-p SJF或-p RR,再做同样的负载,观察平均周转时间怎么变。我第一次跑的时候,发现 SJF 在这个负载下的平均周转时间比 FIFO 还高,吓了一跳。后来才意识到:SJF 的优势只在所有进程同时到达时成立;当到达时间错开,晚到的短作业会让先到的长作业继续等,反而拖慢整体完成时间。这个结论如果只看笔记是记不住的,跑一遍才会留下肌肉记忆。

4.3 编译并运行一个C示例:以并发中的线程创建为例

C 示例部分需要的不是 Python,而是 gcc 编译器。OSTEP 并发章节的示例代码常常依赖common_threads.h这个头文件,它封装了线程创建、互斥锁的基本调用。直接gcc thread.c大概率会报“找不到头文件”,因为头文件被放在独立的 include 目录里。

# 假设示例代码在 code/threads 下,头文件在 code/include 下 gcc -o thread_example code/threads/thread.c -I code/include -lpthread ./thread_example

-I code/include告诉编译器去code/include目录查找头文件,这样#include "common_threads.h"才能命中。-lpthread链接 POSIX 线程库,有些示例只写了pthread_create不写这一项,编译时会报“未定义引用”错误。-o thread_example指定输出文件名,运行./thread_example就能看到结果。

如果你用的是全新 Ubuntu 操作系统,第一件事是安装编译工具链,不然连gcc命令都不存在。执行:

sudo apt install build-essential python3

build-essential包含 gcc、make 等基础工具,python3则保证模拟器脚本能跑。这个准备步骤很多新手会漏,直到敲gcc -v才发现系统里根本没有编译器。装好之后,再去编译 C 示例就不会卡在第一步。

5. 从zip解压到跑通模拟器的避坑检查单:5个现象、原因与解决

这一章的每一条都是我在不同操作系统、不同资料包版本里真实遇到过的。按“现象 -> 原因 -> 解决”写,方便你遇到问题直接对照。

5.1 zip解压失败或提示伪加密:下载不完整或压缩包被“加壳”

现象:在 Linux 下执行unzip xxx.zip,中途报错error: Central directory file header not found,或者某个文件解出来是零字节。在 Windows 下用 WinRAR 打开,它要求输入密码,而你在资源页没看到密码。

原因:一部分是下载时网络中断,zip 文件尾部缺少中央目录,unzip无法解析。另一部分是被“伪加密”处理过:打包工具修改了 zip 的加密标志位,让工具以为文件加密了,但数据本身并没有加密。OSTEP 资料本身是开源公开的,正常情况下不会加密,遇到密码提示基本可以怀疑是伪加密或二次打包。

解决:先测试压缩包完整性。Linux 下用 7z 测试:

7z t "操作系统导论(ostep)笔记_课后习题答案_附加代码.zip"

如果 7z 提示End of archive相关错误,重新下载原包。如果是伪加密,7z x可以直接解压,因为 7-Zip 会尝试忽略加密标志位。系统自带的unzip对加密标志位检查更严格,所以优先用 7z。服务器上如果没有 7z,需要先装p7zip-full。这条经验帮我救回来过好几个号称“损坏”的资料包。

5.2 python脚本在python3下直接报语法错误:模拟器还是python2

现象:运行python3 scheduler.py时报错SyntaxError: Missing parentheses in call to 'print',或者NameError: name 'xrange' is not defined。

原因:OSTEP 早期的模拟器脚本基于 Python 2 编写,而现代发行版默认只有 Python 3。这不是代码坏了,是解释器版本不对。很多两年前下载的资料包里,这类脚本基本都是 Python 2 风格。

解决:优先看系统里有没有python2命令:

python2 scheduler.py -h

如果没有,用2to3把脚本转换成 Python 3 语法:

cp scheduler.py scheduler_py3.py 2to3 -w scheduler_py3.py python3 scheduler_py3.py -h

cp先复制一份备份,避免2to3 -w原地覆盖原文件后找不到原始版。转换后建议逐个脚本跑一遍,因为2to3不一定能把所有兼容性差异都处理干净,尤其是一些老的print和range混用情况。我一般只转换当前要用的脚本,不整个目录批量转换,否则可能引入新的问题。

5.3 无图形环境跑不动turtle模拟器:换无头参数

现象:运行某些带可视化界面的模拟器时,比如地址翻译或页面置换相关脚本,终端报TclError: no display name and no $DISPLAY environment variable。

原因:这些脚本使用 Python 的 Tkinter/turtle 图形库,在 SSH 终端或云服务器上没有图形显示服务,所以一启动就崩溃。这不是代码坏了,是环境缺少显示设备。

解决:先看模拟器帮助里有没有“无头模式”参数,很多 OSTEP 模拟器用-c或-s提供纯文本计算模式。在服务器上,我一般这样做:关掉一切图形相关参数,只用计算模式运行,反正作业题要的是数值,不是动画。如果你在本地桌面环境确实想看图形,可以安装 Tk 支持:

sudo apt install python3-tk

装完再跑就不会报no display name了。要注意,某些老脚本用的是 Python 2 的 Tkinter,在 Python 3 下也会报错,所以还要结合 5.2 的版本问题一起排查。

5.4 编译C示例时找不到common头文件:include路径没加

现象:对并发章节的 C 示例执行gcc thread.c,报错fatal error: common.h: No such file or directory。

原因:书中的示例代码依赖common.h和common_threads.h这两个头文件,它们通常被放在独立的include目录里,而示例代码里用双引号#include "common.h",编译器默认只在当前目录和系统目录查找,当然找不到。

解决:先用find确认头文件实际位置:

find . -name "common_threads.h"

然后编译时加-I参数:

gcc -o thread_example thread.c -I ./include -lpthread

-I ./include把头文件目录加入搜索路径。不要图省事在源码里写/绝对路径/common.h,那样换一台机器就崩。正确做法是让编译命令通过-I控制依赖路径。如果示例还依赖某个common.c实现文件,需要把实现文件也一起编译,否则链接阶段会报“未定义引用”。

5.5 运行结果和答案不一致:先检查题目版本和随机种子

现象:你按答案里的参数运行模拟器,输出却和答案贴的表格对不上,数值看起来差得很随意。

原因:除了策略参数外,最常被忽略的是版本差异。OSTEP 书籍不同版次会修改作业题,模拟器也会更新;资料包里的答案可能是根据上一版脚本算的。另一个原因是随机种子:作业题常给-s 1、-s 34这类数字,少了种子,结果不可复现。

解决:第一步,python3 scheduler.py -h查看参数,确认-s、-j、-l是否和题目一致。第二步,固定随机种子再跑一次。第三步,在答案旁边标注“答案的模拟器版本”和“我用的版本”是否一致。如果数值差异很大,直接以模拟器-c输出为准。答案里的趋势一般不会错,但具体数字可能过时,尤其是转载多轮的资料包。

6. 进阶验证:用附加代码批量跑调度对比实验,检验你是否真读懂了

只看单个策略的输出不算读懂,能设计一个对比实验,才说明你把参数和算法串起来了。我每次拿到新的 OSTEP 资料包,都会先固定一个随机种子,把相关章节的模拟器至少跑两遍。下面这个例子用三种策略对比同一组负载,路径要按实际目录调整。

for policy in FIFO SJF RR; do echo "== $policy ==" python3 scheduler.py -p $policy -l 0,20,5,15,10,5 -c | grep "Average turnaround" done

这个循环里只改-p,负载列表始终是0,20、5,15、10,5三个进程,所以是控制变量实验。grep "Average turnaround"过滤出平均周转时间,方便把三种策略的输出并排对比。如果策略是 RR,还可以加-q 2调整时间片大小,观察时间片对响应时间的影响。

跑完你会看到一个很有意思的结果:在这个负载下,SJF 不一定比 FIFO 好。原因不是书错了,而是教科书场景通常假设所有进程同时到达;当到达时间错开后,晚到的短作业可能插队,让先到的长作业继续等,整体周转时间反而恶化。把这个现象写进笔记旁边,你才算真正理解了调度。

我习惯把每次实验用的命令、参数和输出行保留下来,整理成一张自己的结果表,然后在表格旁边写一句“我看到了什么,为什么”。这样期末复习时不用重新跑,只看表格就能回忆起当时的判断。这个习惯帮我节省了大量时间,也让别人争论调度算法优劣时,我能直接给出可复现的实验结果。希望这个流程也帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/28 11:56:34

乳腺细胞分割数据集:512×512双通道PNG结构与PyTorch加载规范

简介&#xff1a;本资源是面向医学图像分析初学者与AI医疗方向研究者的乳腺细胞癌症二分类分割数据集&#xff0c;聚焦于细胞级病灶定位任务&#xff0c;适用于U-Net等分割模型的训练验证与可视化教学。压缩包共103个文件&#xff08;101张512512 PNG格式原始图像及对应mask、1…

作者头像 李华
网站建设 2026/9/28 11:52:00

免费统计工具的数据保留多久?

直答&#xff1a;免费版数据保留不是永久的&#xff0c;存储周期通常写在隐私政策里&#xff0c;选工具前先翻一遍&#xff0c;重要历史报表建议定期导出备份。你用一个免费统计工具跑了半年&#xff0c;突然想回头对比"去年同期"的数据——结果发现免费版只能看最近…

作者头像 李华
网站建设 2026/9/28 11:50:31

绍兴上虞上瑞风机有限公公司口碑如何

绍兴上虞上瑞风机有限公司是专注于通风暖通设备一站式配套的专业贸易代理商&#xff0c;依托多源头原厂供应链与全国无区域接单服务&#xff0c;为各地工程客户提供通风排烟风机、油烟净化设备、风口风阀等产品供应及配套服务&#xff0c;解决工程采购领域的渠道、价格、服务痛…

作者头像 李华
网站建设 2026/9/28 11:48:44

53 张图被传上公网,OpenAI 却通知不了本人

9 月 25 日&#xff0c;OpenAI 在博客里承认&#xff1a;自家 AI 智能体把 53 张用户上传的图片&#xff0c;传到了第三方图像托管网站&#xff0c;拿到链接就能打开。更麻烦的是后半句——它联系不上这些图的主人。 边界先说清。图片不在公开索引页上&#xff0c;搜索引擎翻不…

作者头像 李华
网站建设 2026/9/28 11:44:45

基于深度学习的人流量检测系统Python源码毕业设计实战

简介&#xff1a;这份资源是面向高校计算机、人工智能及相关专业学生的毕业设计完整项目包&#xff0c;主题为基于深度学习的人流量检测系统&#xff0c;适合作为毕业设计、课程设计或期末大作业的参考方案&#xff0c;也便于希望入门计算机视觉与目标检测的开发者学习实践。压…

作者头像 李华