BUAA-2025-OS-Lab6
lab6 实验报告思考题Thinking 6.1示例代码中父进程操作管道的写端子进程操作管道的读端。如果现在想让父进程作为“读者”代码应当如何修改代码如下switch(fork()){case-1:break;case0:/* 子进程- 作为管道的写者 */close(fildes[0]);/* 关闭不用的读端 */write(fildes[1],Hello world\n,12);/* 向管道中写数据 */close(fildes[1]);/* 写入结束关闭写端 */exit(EXIT_SUCCESS);default:/* 父进程- 作为管道的读者 */close(fildes[1]);/* 关闭不用的写端 */read(fildes[0],buf,100);/* 从管道中读数据 */printf(father-process read:%s,buf);/* 打印读到的数据 */close(fildes[0]);/* 读入结束关闭读端 */exit(EXIT_SUCCESS);}Thinking 6.2上面这种不同步修改 pp_ref 而导致的进程竞争问题在 user/lib/fd.c 中的dup 函数中也存在。请结合代码模仿上述情景分析一下我们的dup函数中为什么会出现预想之外的情况在dup函数中dup函数的作用是让新旧文件描述符共享底层的物理内存和状态信息其中我们先对复制的是文件描述符的映射关系然后再对文件描述符中的文件页进行复制如果文件描述符指向一个管道文件再dup函数进行过程中可能出现在复制文件描述符之后、复制文件页之前文件描述符的pageref等于管道的引用次数如果此时被外部中断就会产生对引用次数的错误判断导致read或write异常终止例如以下伪代码pipe(p);if(fork()0){dup(p[1]);read(p[0]);}else{dup(p[0]);write(p[1]);}若子进程先执行完dup后中断父进程在执行完dup的文件描述符复制后中断此时pageref(p[0]) pageref(p) 1子进程进入read函数后发现pageref(p[0]) pageref(p) 1使得read被错误的结束Thinking 6.3阅读上述材料并思考为什么系统调用一定是原子操作呢如果你觉得不是所有的系统调用都是原子操作请给出反例。希望能结合相关代码进行分析说明。只有syscall_*开头的系统调用是原子操作因为在这些系统调用开始前通过修改SR寄存器的值关闭了外部中断从而在执行这些系统调用时不会被例如时间片到等外部中断影响复杂系统调用如read则不是原子操作假设一个进程调用read(fd, buffer, 1024)试图从一个硬盘文件中读取 1024 字节进程从用户态陷入内核态开始执行read系统调用内核向硬盘控制器发出指令读取数据硬盘是一个非常慢的设备CPU 的速度比它快几个数量级内核不可能为了等硬盘而停止运转此时内核会将当前进程的状态从RUNNING改为BLOCKED(或WAITING)并将它从调度队列中移除然后调度器 (Scheduler) 会选择另一个处于READY状态的进程来运行过了很久几毫秒后硬盘通过一次硬件中断通知 CPU“数据准备好了”内核响应中断将数据从硬件缓冲区复制到用户指定的buffer然后将原来那个进程的状态改回READY等待下一次被调度Thinking 6.4仔细阅读上面这段话并思考下列问题• 按照上述说法控制 pipe_close中 fd和 pipe unmap的顺序是否可以解决上述场景的进程竞争问题给出你的分析过程。• 我们只分析了close时的情形在 fd.c中有一个dup函数用于复制文件描述符。试想如果要复制的文件描述符指向一个管道那么是否会出现与 close类似的问题请模仿上述材料写写你的理解。可以解决初始时pageref(p[0]) 2pageref(p[1]) 2pageref(p) 4子进程运行先执行完close(p[1])解除了p[1]的映射时钟中断父进程运行执行完close(p[0])中解除对 p[0] 的映射后pageref(p[0]) 1, pageref(p[1]) 1, pageref(p) 3此时不满足写端关闭的条件会出现类似的问题在Thinking 6.2中已经提到在要复制的文件描述符指向一个管道时如果先对文件描述符p[0]进行复制就会出现pageref(p) pageref(p[0])的情况Thinking 6.5思考以下三个问题。• 认真回看Lab5文件系统相关代码弄清打开文件的过程。• 回顾Lab1与Lab3思考如何读取并加载ELF文件。• 在Lab1 中我们介绍了 data text bss 段及它们的含义data 段存放初始化过的全 局变量bss段存放未初始化的全局变量。关于memsize和filesize我们在Note 1.3.4中也解释了它们的含义与特点。关于Note1.3.4注意其中关于“bss段并不在文 件中占数据”表述的含义。回顾Lab3并思考elf_load_seg()和load_icode_mapper() 函数是如何确保加载ELF文件时bss段数据被正确加载进虚拟内存空间。bss段 在ELF中并不占空间但ELF加载进内存后bss段的数据占据了空间并且初始 值都是0。请回顾elf_load_seg() 和 load_icode_mapper() 的实现思考这一点 是如何实现的打开文件的过程利用fd open(prog, O_RDONLY)根据文件名调用open函数然后调用fsipc_open函数向文件系统进程发出请求在文件系统进程中通过serve_open函数将文件从磁盘加载到内存中返回共享信息这时文件打开读取并加载ELF文件先用elf_form和readn读出ELF头遍历每个程序头判断是否为PT_LOAD类型以是否加载到内存中按段解析完后利用elf_load_seg函数将每个段映射到对应的地址空间中在lib/elfloader.c中elf_load_seg完成对bss段的初始化/* Step 2: alloc pages to reach sgsize when bin_size sgsize. */while(isgsize){if((rmap_page(data,vai,0,perm,NULL,MIN(sgsize-i,PAGE_SIZE)))!0){returnr;}iPAGE_SIZE;}Thinking 6.6通过阅读代码空白段的注释我们知道将标准输入或输出定向到文件需要 我们将其dup到0或1号文件描述符fd。那么问题来了在哪步0和1被“安排”为 标准输入和标准输出请分析代码执行流程给出答案。通过console.c中的函数进行处理intopencons(void){intr;structFd*fd;if((rfd_alloc(fd))0){returnr;// 分配一个新的文件描述符结构}if((rsyscall_mem_alloc(0,fd,PTE_D|PTE_LIBRARY))0){returnr;// 为文件描述符结构分配一页内存}fd-fd_dev_iddevcons.dev_id;// 将文件描述符与特定的设备关联起来fd-fd_omodeO_RDWR;// 设定文件描述符的打开模式returnfd2num(fd);// 内存地址转换为整数文件描述符编号}首先调用opencons()获得一个指向控制台的文件描述符接着使用dup系统调用将这个fd_num复制到 0 号标准输入 stdin 和 1 号标准输出 stdout 文件描述符上完成这一步后shell 以及它后续创建的所有子进程就都默认将键盘作为标准输入将屏幕作为标准输出了Thinking 6.7在 shell 中执行的命令分为内置命令和外部命令。在执行内置命令时shell不需要fork 一个子shell如 Linux 系统中的 cd 命令。在执行外部命令时 shell 需要 fork 一个子shell然后子 shell 去执行这条命令。​ 据此判断在MOS 中我们用到的 shell 命令是内置命令还是外部命令请思考为什么 Linux 的 cd 命令是内部命令而不是外部命令在MOS中我们用到的 shell 命令是外部命令在我们的shell中其执行过程为调用 readline 读入用户输入的命令fork 出一个子进程子进程执行用户的命令执行结束后子进程结束。父进程在此等待子进程父进程等待子进程结束后返回循环开始读入用户的下一个命令可见shell是一个外部命令对于cd命令其要求改变父进程的状态单靠子进程无法完成该命令因此cd命令是一个内部命令Thinking 6.8在你的 shell 中输入命令 ls.b | cat.b motd。• 请问你可以在你的shell 中观察到几次spawn分别对应哪个进程• 请问你可以在你的shell 中观察到几次进程销毁分别对应哪个进程2次spawn分别对应ls.b命令和cat.b命令通过shell创建的进程4次进程销毁9004、9805、8806、8003分别对应ls.b、cat,b通过shell创建的进程和通过管道创建的shell进程和main函数创建的shell进程难点分析管道对于判断管道是否关闭的正确性在非原子操作中任何操作都有可能被外部中断所影响都有可能在外部中断的干扰下产生错误的结果。pipe_close和dup并非单一、不可分割的硬件指令。它们是由多个步骤组成的函数例如“解除A的映射”和“解除B的映射”。在这两个步骤之间存在一个时间间隔允许进程切换等并发事件插入破坏数据的一致性对于这个问题的解决可以通过对于执行逻辑的变换调整unmap的顺序即首先解除fd的映射再解除pipe的映射在这种情况下使得 fd引用次数的-1 先于 pipepageref(pipe) pageref(fd)仍成立即使此时发生中断也不会影响判断管道是否关闭的正确性shell增加一个通过外部命令驱动的shell的一个难点在于对于整个MOS操作系统整体的理解对于spawn函数的实现我们需要综合运用到之前lab的知识按照从文件系统打开对应的文件、申请新的进程控制块、将目标程序加载到子进程的地址空间中并为它们分配物理页面、为子进程初始化地址空间。对于栈空间由于spawn需要将命令行参数传递给用户程序 所以要将参数也写入用户栈中、设置子进程的寄存器栈指针sp和用户程序入口EPC、将父进程的共享页面映射到子进程的地址空间中、设置子进程可执行这些步骤来完成对于shell相关的函数spawn装载新的ELF文件执行新的程 序sh.c中的主函数调用 readline 读入用户输入的命令、fork 出一个子进程、子进程执行用户的命令执行结束后子进程结束。父进程在此等待子进程、父进程等待子进程结束后返回循环开始读入用户的下一个命令readline从标准输入读入一行用户读入的命令gettoken将命令字符串分割提取命令中基本单元parsecmd、runcmd命令解析与执行函数dupdup(0, 1)实际上是对文件描述符的复制其作用是将文件描述符 上是指将输入输出都连接到终端在后续需要重定向时使用 dup 把想要重定向 fd 覆盖到01上也是类似的。通过这样的方法可以实现更高 程度的解耦。实验体会Lab6课下实验主要分为两部分第一部分是完善文件系统为其增加管道这种进程间通信方式同时在对于管道通信时的操作也就是对于多进程之间的控制需要进行一个全面的理解第二部分是补充shell代码在MOS操作系统增加一个通过外部命令驱动的shell首先要实现使用ELF文件创建进程和spawn函数随后通过对输入输出的定位对于输入的命令进行解析并进行处理对于整个lab6的课下实验逻辑较为清晰也比较容易理解需要进行补全的代码似乎也是历次课下实验中最少的但对于整个shell的狗工作流程以及执行的顺序有一个较清晰的了解还需要在补全代码之外的进一步分析与整理

相关新闻

AI Agent构建全栈应用实战:2026年开发流程与踩坑指南

AI Agent构建全栈应用实战:2026年开发流程与踩坑指南

2026年了,聊“AI Agent 构建全栈应用”已经不是什么未来概念,而是团队里每天都在发生的日常。我自己从最早拿它写点脚本,到后来让它独立搭前后端、设计数据库、补测试用例,再到最近两个月,干脆把一个内部工具交给 Agen…

2026/10/13 9:55:06 阅读更多 →
浏览器端扩散模型生成3D地形:小模型+WebGPU工程实践

浏览器端扩散模型生成3D地形:小模型+WebGPU工程实践

1. 浏览器里跑地形生成,这件事到底有多难 第一次看到有人把扩散模型塞进浏览器里跑,而且生成的是三维地形高度图,我的反应是:这要么是个玩具,要么作者在工程上做了相当狠的取舍。原因很简单,扩散模型在大众…

2026/10/13 9:55:06 阅读更多 →
RocketMQ多主多从集群部署实战:Docker Compose高可用架构详解

RocketMQ多主多从集群部署实战:Docker Compose高可用架构详解

1. 为什么非得搞“多主多从”?——从单点故障说到消息堆积的现实压力RocketMQ不是装上就能高枕无忧的中间件。我最早在某电商模拟项目X里用单NameServer加单Broker跑订单通知,测试环境风平浪静,一上预发就崩了两次:一次是Broker进…

2026/10/13 9:55:06 阅读更多 →

最新新闻

Nacos配置中心中文乱码怎么办?SpringBoot环境UTF-8编码配置指南

Nacos配置中心中文乱码怎么办?SpringBoot环境UTF-8编码配置指南

搞微服务的同学,不管在哪个团队,迟早会在Nacos配置中心里碰上一次乱码。我这两年接到过不少工单,报的都是同一个毛病:本地启动一切正常,一到测试或生产环境,前端拿到的中文全变成问号,或者日志里…

2026/10/13 10:38:24 阅读更多 →
用Python从零构建抓包工具:实时抓包、离线分析与代理调试

用Python从零构建抓包工具:实时抓包、离线分析与代理调试

做小程序后端联调时,我经常遇到这种局面:客户端明明发了某个请求,服务端日志里却什么都没有;真机测试一切正常,一上体验版就超时;前端说参数格式没问题,后端说根本不是自己定义的字段。两边都拿…

2026/10/13 10:38:24 阅读更多 →
DDoS攻击原理与防御实战指南:从攻击流程到应急响应

DDoS攻击原理与防御实战指南:从攻击流程到应急响应

做运维这些年,被半夜电话吵醒的次数已经数不清了——不是服务器宕机,就是有人在打你的站。DDoS 这三个字母,圈子里早就讲烂了,但真正能把它讲透、讲得让零基础的人看懂并知道怎么应对的内容,反而没多少。大部分文章都停…

2026/10/13 10:38:24 阅读更多 →
CGAssistant:CrossGate cg_item_6000 协议包解析与修改工具

CGAssistant:CrossGate cg_item_6000 协议包解析与修改工具

简介:CGAssistant是一款面向CrossGate游戏玩家的C开发的自动化辅助工具,聚焦于cg_item_6000功能模块,适用于希望提升游戏操作效率与脚本化交互能力的进阶玩家及逆向/外挂开发学习者。资源包共2088个文件,主体为1158个JavaScript逻…

2026/10/13 10:38:24 阅读更多 →
Windows Server 2012 R2 网卡驱动精准匹配与NDIS栈验证指南

Windows Server 2012 R2 网卡驱动精准匹配与NDIS栈验证指南

简介:本资源为Windows Server 2012 R2专用64位网卡驱动程序合集,面向企业IT运维人员、系统管理员及虚拟化平台部署工程师,专用于解决该版本服务器在新硬件(如Intel X710、Broadcom NetXtreme等主流网卡)上因驱动缺失或…

2026/10/13 10:38:23 阅读更多 →
VS Code中高效读取HDF5文件:从插件预览到h5py实战

VS Code中高效读取HDF5文件:从插件预览到h5py实战

你有没有遇到过这种场面:同事或者对接方丢给你一个.h5文件,说是训练好的模型权重,或者某次实验的全部原始数据,你兴冲冲地在 VS Code 里双击打开,结果满屏都是二进制乱码。这个画面我见过太多次了,包括我自…

2026/10/13 10:37:18 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →