【操作系统xv6】学习记录5--实验1 Lab: Xv6 and Unix utilities
ref:https://pdos.csail.mit.edu/6.828/2020/xv6.html

实验:Lab: Xv6 and Unix utilities
环境搭建
实验环境搭建:https://blog.csdn.net/qq_45512097/article/details/126741793
搭建了1天,大家自求多福吧,哎。~搞环境真是折磨人
anyway,我搞好了:

开整实验
内容1:sleep
创建user/sleep.c
在Makefile中UPROGS下添加$U/_sleep
编写sleep.c
运行测试程序grade-lab-util并且指明要测试的函数。如 grade-lab-util sleep
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"void main(int argc, char *argv[])
{if(argc != 2){// 2 输出到哪里,输出内容,fprintf(2,"usage:sleep <time> \n");exit(1);}int sec = atoi(argv[1]);sleep(sec); //printf("usage:sleep %d \n",sec);exit(0);
}
修改makefile,只需要改这一个地方

验证命令,要退出qume才能执行,否则会报错,
这种时候单项验证sleep
./grade-lab-util sleep
justin@DESKTOP-NIK28BI:~/vc6/xv6-labs-2020$ ./grade-lab-util sleep
fatal: detected dubious ownership in repository at '/mnt/d/code/vc6/xv6-labs-2020'
To add an exception for this directory, call:git config --global --add safe.directory /mnt/d/code/vc6/xv6-labs-2020
make: 'kernel/kernel' is up to date.
== Test sleep, no arguments == fatal: detected dubious ownership in repository at '/mnt/d/code/vc6/xv6-labs-2020'
To add an exception for this directory, call:git config --global --add safe.directory /mnt/d/code/vc6/xv6-labs-2020
sleep, no arguments: OK (1.3s)
== Test sleep, returns == sleep, returns: OK (0.8s)
== Test sleep, makes syscall == sleep, makes syscall: OK (1.0s)
内容2:pingpong
Write a program that uses UNIX system calls to ‘‘ping-pong’’ a byte between two processes over a pair of pipes, one for each direction.
The parent should send a byte to the child;
the child should print “: received ping”, where is its process ID, write the byte on the pipe to the parent(这里没有指定具体写什么内容,什么都可以,只是作为标志,且这个标志不需要也不要打印,否则会影响测评), and exit;
the parent should read the byte from the child, print “: received pong”, and exit.
Your solution should be in the file user/pingpong.c.
#include "kernel/types.h"
#include "user/user.h"
#define RD 0 // pipe的read端
#define WR 1 // pipe的write端
int main(){char buf[10]; //缓冲区字符数组,存放传递的信息int fd_c2p[1]; // child->parentint fd_p2c[1]; // parent->childint ret1 = pipe(fd_c2p);int ret2 = pipe(fd_p2c);if(ret1==-1){printf("child->parent pipe");exit(1);}if(ret2==-1){printf("parent->child pipe");exit(1);}int pid = fork();if(pid==0){//子进程// 关闭父管道的写入端和子管道的读取端close(fd_p2c[WR]); // 显示关闭是为了严谨,不关闭不会报错close(fd_c2p[RD]); //read(fd_p2c[RD],buf,4);printf("child:%d received %s\n", getpid(),buf);write(fd_c2p[WR],"pong",4);}else if(pid>0){close(fd_p2c[RD]);close(fd_c2p[WR]);// 父进程write(fd_p2c[WR],"ping",4);int status;int child_id = wait(&status);printf("child:%d done!\n",child_id);read(fd_c2p[RD],buf,4);printf("parent:%d received %s\n", getpid(),buf);printf("parent:%d done!\n", getpid());}exit(0);return 0;
}
hart 1 starting
hart 2 starting
init: starting sh
$ pingpong
child:4 received ping
child:4 done!
parent:3 received pong
parent:3 done!
注意没有exit(0); 会出现乱码,原因未知,欢迎大神留言解惑:
hart 1 starting
hart 2 starting
init: starting sh
$ pingpong
child:4 received ping
usertrap(): unexpected scause 0x000000000000000d pid=4sepc=0x0000000000000100 stval=0x0000000000003f64
child:4 done!
parent:3 received pong
parent:3 done!
usertrap(): unexpected scause 0x000000000000000d pid=3sepc=0x0000000000000100 stval=0x0000000000003f64
内容3:Primes(素数,难度:Moderate/Hard)
YOUR JOB
使用管道编写prime sieve(筛选素数)的并发版本。这个想法是由Unix管道的发明者Doug McIlroy提出的。请查看这个网站(翻译在下面),该网页中间的图片和周围的文字解释了如何做到这一点。您的解决方案应该在user/primes.c文件中。
您的目标是使用pipe和fork来设置管道。第一个进程将数字2到35输入管道。对于每个素数,您将安排创建一个进程,该进程通过一个管道从其左邻居读取数据,并通过另一个管道向其右邻居写入数据。由于xv6的文件描述符和进程数量有限,因此第一个进程可以在35处停止。
提示:
- 请仔细关闭进程不需要的文件描述符,否则您的程序将在第一个进程达到35之前就会导致xv6系统资源不足。
- 一旦第一个进程达到35,它应该使用wait等待整个管道终止,包括所有子孙进程等等。因此,主primes进程应该只在打印完所有输出之后,并且在所有其他primes进程退出之后退出。
- 提示:当管道的write端关闭时,read返回零。
- 最简单的方法是直接将32位(4字节)int写入管道,而不是使用格式化的ASCII I/O。
- 您应该仅在需要时在管线中创建进程。
- 将程序添加到Makefile中的UPROGS。
如果您的解决方案实现了基于管道的筛选并产生以下输出,则是正确的:
$ make qemu
...
init: starting sh
$ primes
prime 2
prime 3
prime 5
prime 7
prime 11
prime 13
prime 17
prime 19
prime 23
prime 29
prime 31
$
考虑所有小于1000的素数的生成。Eratosthenes的筛选法可以通过执行以下伪代码的进程管线来模拟:
p = get a number from left neighbor
print p
loop:n = get a number from left neighborif (p does not divide n)send n to right neighbor
p = 从左邻居中获取一个数
print p
loop:n = 从左邻居中获取一个数if (n不能被p整除)将n发送给右邻居

生成进程可以将数字2、3、4、…、1000输入管道的左端:行中的第一个进程消除2的倍数,第二个进程消除3的倍数,第三个进程消除5的倍数,依此类推。
这是我调试版本的代码,没有在xv6中打印,可以在任何linux中运行。
取数据:lpipe,写数据rpipe, 从图中可以看到,每个矩形的操作是重复的,所以应该用递归调用function primes,
而且每次递归调用,生成新的子进程,继续递归调用。
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#define RD 0
#define WR 1
/*** @brief 寻找素数* @param lpipe 左邻居管道*/
void primes(int lpipe[2]){ //接收的参数当左通道用close(lpipe[WR]);int first;if(read(lpipe[RD],&first,sizeof(int))==sizeof(int)){ // 读到了【左管道】(第一次是main)送过来的数据printf("prime %d\n",first);printf("get first:%d\n",first);// 定义右管道int rpipe[2];pipe(rpipe); // 生成右管道,做数据过滤int data;while(read(lpipe[RD], &data, sizeof(int))==sizeof(int)){if (data % first){// 除尽的过滤掉,除不尽的留下,放到右管道 write(rpipe[WR], &data, sizeof(int));}}if (fork() == 0) {primes(rpipe); // 递归的思想,但这将在一个新的进程中调用} else {close(rpipe[WR]);// 关闭右管道的写wait(0);//等待回收子进程}}}
int main(){int p[2];pipe(p);int res;for (size_t i = 2; i <= 35; i++){// 依次写入初始数据 2,3,4,...35res = write(p[WR],&i,sizeof(size_t));printf("pid:%d, send:%d, res:%d\n",getpid(),i,res);}if (fork()==0){ //子进程做筛选素数操作,是递归筛选primes(p); }else{//父进程啥也不干,等着回收子进程即可close(p[WR]); // 这里写关不关闭无所谓,但是谨慎起见,还是关闭为好close(p[RD]);//这里必须要关闭读,否则子进程无法从管道读取数据。wait(0); }exit(0); }
main函数的 close(p[RD]);//这里必须要关闭读,否则子进程无法从管道读取数据。
读操作只能确保开放给一个进程!这个题目是很难的!
4.find(难度:Moderate)
YOUR JOB
写一个简化版本的UNIX的find程序:查找目录树中具有特定名称的所有文件,你的解决方案应该放在user/find.c

5.xargs(难度:Moderate)
YOUR JOB
编写一个简化版UNIX的xargs程序:它从标准输入中按行读取,并且为每一行执行一个命令,将行作为参数提供给命令。你的解决方案应该在user/xargs.c
下面的例子解释了xargs的行为
$ echo hello too | xargs echo bye
bye hello too
$
注意,这里的命令是echo bye,额外的参数是hello too,这样就组成了命令echo bye hello too,此命令输出bye hello too
请注意,UNIX上的xargs进行了优化,一次可以向该命令提供更多的参数。 我们不需要您进行此优化。 要使UNIX上的xargs表现出本实验所实现的方式,请将-n选项设置为1。例如
$ echo "1\n2" | xargs -n 1 echo line
line 1
line 2
$
提示:
- 使用fork和exec对每行输入调用命令,在父进程中使用wait等待子进程完成命令。
- 要读取单个输入行,请一次读取一个字符,直到出现换行符(‘\n’)。
- kernel/param.h声明MAXARG,如果需要声明argv数组,这可能很有用。
- 将程序添加到Makefile中的UPROGS。
- 对文件系统的更改会在qemu的运行过程中保持不变;要获得一个干净的文件系统,请运行make clean,然后make qemu
- xargs、find和grep结合得很好
ref:https://xv6.dgs.zone/labs/requirements/lab1.html
相关文章:
【操作系统xv6】学习记录5--实验1 Lab: Xv6 and Unix utilities
ref:https://pdos.csail.mit.edu/6.828/2020/xv6.html 实验:Lab: Xv6 and Unix utilities 环境搭建 实验环境搭建:https://blog.csdn.net/qq_45512097/article/details/126741793 搭建了1天,大家自求多福吧,哎。~搞环境真是折磨…...
Python从入门到网络爬虫(控制语句详解)
前言 做任何事情都要遵循一定的原则。例如,到图书馆去借书,就需要有借书证,并且借书证不能过期,这两个条件缺一不可。程序设计亦是如此,需要使用流程控制实现与用户的交流,并根据用户需求决定程序“做什么…...
transbigdata笔记:数据预处理
0 数据 使用 transbigdata/docs/source/gallery/data/TaxiData-Sample.csv at main ni1o1/transbigdata (github.com) 和transbigdata/docs/source/gallery/data/sz.json at main ni1o1/transbigdata (github.com) 0.1 导入库 import transbigdata as tbd import pandas …...
java中解码和编码出现乱码原因
一、UTF-8和GBK编码方式 如果采用的是UTF-8的编码方式,那么1个英文字母 占 1个字节,1个中文占3个字节如果采用GBK的编码方式,那么1个英文字母 占 1个字节,1个中文占2个字节 二、idea和eclipse的默认编码方式 其实idea和eclipse的…...
60V降压3.3V稳压芯片 60V降压5V稳压芯片60V降压12V稳压芯片
60V降压3.3V稳压芯片、60V降压5V稳压芯片和60V降压12V稳压芯片是针对不同输出电压需求的降压稳压芯片。这些芯片通常被用于工业控制、通信设备、汽车电子和其他需要高电压输入并提供稳定输出电压的场合。 这些芯片通常具有高效率、低功耗和高稳定性的特点,能够在输…...
01第一个Mybatis程序+引入Junit+引入日志文件logback
Mybatis MyBatis本质上就是对JDBC的封装,通过MyBatis完成CRUD。而对于JDBC,SQL语句写死在Java程序中,不灵活。改SQL的话就要改Java代码。违背开闭原则OCP。对于事务机制,MyBatis支持 或managed模式,JDBC模式中MyBatis…...
音乐制作软件Studio One mac有哪些特点
Studio One mac是一款专业的音乐制作软件,该软件提供了全面的音频编辑和混音功能,包括录制、编曲、合成、采样等多种工具,可用于制作各种类型的音乐,如流行音乐、电子音乐、摇滚乐等。 Studio One mac软件特点 1. 直观易用的界面&…...
开源C语言库Melon之日志模块
本文向大家介绍一个名为Melon的开源C语言库的日志模块。 简述Melon Melon是一个包含了开发中常用的各类组件的开源C语言库,支持Linux、MacOS、Windows系统,可用于服务器开发亦可用于嵌入式开发,无第三方软件依赖,安装简单&…...
[NOIP2006 提高组] 作业调度方案(修改)
题目: 这里对于之前的题目进行修改记录。果然还是受不了等待,利用晚饭时间又看了这个题目。于是发现了问题。 之前的博客:https://blog.csdn.net/KLSZM/article/details/135522867?spm1001.2014.3001.5501 问题修改描述 上午书写的代码中是…...
uniapp微信小程序投票系统实战 (SpringBoot2+vue3.2+element plus ) -全局异常统一处理实现
锋哥原创的uniapp微信小程序投票系统实战: uniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )_哔哩哔哩_bilibiliuniapp微信小程序投票系统实战课程 (SpringBoot2vue3.2element plus ) ( 火爆连载更新中... )共计21条视频…...
浏览器缓存引发的odoo前端报错
前两天,跑了一个odoo16项目,莫名其妙的前端报错, moment.js 报的错, 这是一个时间库,不是我自己写的代码,我也没做过任何修改,搞不清楚为什么报错。以为是odoo的bug,所以从gitee下载…...
如何搭建开源知识库软件AFFiNE并实现公网环境远程协作【内网穿透】
目录 前言 1. 使用Docker安装AFFINE 2. 安装cpolar内网穿透工具 3. 配置AFFINE公网访问地址 4. 实现公网远程访问AFFINE 结语 作者简介: 懒大王敲代码,计算机专业应届生 今天给大家聊聊如何搭建开源知识库软件AFFiNE并实现公网环境远程协作【内网穿…...
记忆泊车信息安全技术要求
一.概述 1.1 编写目的 记忆泊车过程涉及车辆通信、远程控制车辆等关键操作,因此需要把信息安全考虑进去,确保整个自动泊车过程的信息安全。 1.2 编写说明 此版为信息安全需求,供应商需要整体的信息安全方案。 1.3 适用范围 …...
开源分布式任务调度系统DolphinScheduler本地部署与远程访问
文章目录 前言1. 安装部署DolphinScheduler1.1 启动服务 2. 登录DolphinScheduler界面3. 安装内网穿透工具4. 配置Dolphin Scheduler公网地址5. 固定DolphinScheduler公网地址 前言 本篇教程和大家分享一下DolphinScheduler的安装部署及如何实现公网远程访问,结合内…...
C++day3作业
完善对话框,点击登录对话框,如果账号和密码匹配,则弹出信息对话框,给出提示”登录成功“,提供一个Ok按钮,用户点击Ok后,关闭登录界面,跳转到其他界面 如果账号和密码不匹配…...
设计模式⑤ :一致性
一、前言 有时候不想动脑子,就懒得看源码又不像浪费时间所以会看看书,但是又记不住,所以决定开始写"抄书"系列。本系列大部分内容都是来源于《 图解设计模式》(【日】结城浩 著)。该系列文章可随意转载。 …...
Android通过Recyclerview实现流式布局自适应列数及高度
调用 FlowAdapter 跟普通recyclerview一样使用 RecyclerView rvLayout holder.getView(R.id.spe_tag_layout); FlowAdapter rvAdapter new FlowAdapter(); FlowLayoutManager flowLayoutManager new FlowLayoutManager(); rvLayout.setLayoutManager(flowLayoutManager); r…...
AlexNet(fashion-mnist)
前言 AlexNet相较于LeNet-5具有更深的网络结构,采用relu激活函数。 AlexNet 参数更多,计算量更大,计算速度更慢,精度更高。 netnn.Sequential(nn.Conv2d(1,96,kernel_size11,stride4,padding1),nn.ReLU(),nn.MaxPool2d(kernel…...
2024新年烟花代码完整版
文章目录 前言烟花效果展示使用教程查看源码HTML代码CSS代码JavaScript 新年祝福 前言 在这个充满希望和激动的2024年,新的一年即将拉开帷幕,而数字科技的创新与发展也如火如荼。烟花绚丽多彩的绽放,一直以来都是新年庆典中不可或缺的元素。…...
Fontfabric:一款字体与设计的完美结合
一、产品介绍 Fontfabric是一款由国际字体设计公司Fontfabric开发的字体设计软件。它提供了一整套完整的字体设计工具,让用户可以轻松地创建、设计和定制自己的字体。Fontfabric拥有丰富的字体库,包括各种风格和类型,能够满足用户在不同场景…...
如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...
【算法训练营Day07】字符串part1
文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接:344. 反转字符串 双指针法,两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...
UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)
UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中,UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化…...
什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南
文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果。 方法一:使用 XML 的 <foreach> 标签ÿ…...
安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲
文章目录 前言第一部分:体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分:体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...
破解路内监管盲区:免布线低位视频桩重塑停车管理新标准
城市路内停车管理常因行道树遮挡、高位设备盲区等问题,导致车牌识别率低、逃费率高,传统模式在复杂路段束手无策。免布线低位视频桩凭借超低视角部署与智能算法,正成为破局关键。该设备安装于车位侧方0.5-0.7米高度,直接规避树枝遮…...
API网关Kong的鉴权与限流:高并发场景下的核心实践
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中,API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关,Kong凭借其插件化架构…...
