Lab1 的内容是简单的熟悉 xv6 操作系统和怎么做实验,官网上对实验难度的描述是easy
, easy
, moderate/hard
, moderate
, moderate
。
我感觉是moderate
, moderate
, ??
, hard
, ???
可能和我看不懂他自带的教材有关系 :cry:
开始实验前,建议阅读一下 xv6 系统的源码,看看定式是怎样的(至少要知道应该引入哪些头文件),强烈建议阅读 K&R C
(深刻的认识到对 C 语言的理解完全不够,函数都认不全:pensive:)
一定,一定,读完一章之后,再来做实验
Sleep (easy)
让系统休息一会……
代码并不难,最难的地方应该在于,如果不阅读源码或求助的话,连头文件都不知道怎么include
。
官网上有一些 Hints
,虽然我感觉这一题的并没有什么用。
解题思路如下:
- 首先处理无参数的情况,异常退出。
- 调用库函数
sleep
,参数为 argv
数组的第二个参数,使用 atoi
函数将字符串转为数值。
添加文件 user/sleep.c
。
代码如下:
PingPong(easy)
通过管道在子进程与父进程间传递信息,如下图所示:
不论对子进程还是父进程,管道都是单向通信,因此需要及时关闭管道的出入口,防止读写失败。
这里解题的思路如下:
- 首先,父进程通过管道向子进程写入信息,随后等待子进程的运行结束。
- 子进程开始运行,首先读入父进程传递的信息,随后打印子进程的
pid
。
- 子进程通过管道向父进程写入信息后,结束子进程。
- 返回父进程,父进程读入子进程传递的信息,随后打印自己的
pid
。
- 进程结束。
添加文件 user/pingpong.c
代码如下:
Primes(moderate/hard)
一定记得去看Bell Labs and CSP Threads (swtch.com) 这个页面的详细描述。
本题旨在通过 fork
与 pipe
来实现一个流水线,进而实现一个并行化的素数筛。
为简洁描述,对此,不再使用父进程与子进程的概念,只使用出现的先后次序来描述。
解题思路为:
- 第一个进程将 2 到 35 传入第二个进程。
- 前一个进程传入的第一个数必然为质数(例如第一个到第二个,第一个数为 2),于是,遍历后续的数字,将不能被此数字整除的数传递给下一个进程。
- 反复进行第二步操作,直到遍历完所有数字。
添加文件 user/primes.c
上述的操作,在描述上是迭代的进行,但实际上应当是递归式进行的,具体可见代码:
Find(moderate)
建议多看几遍官方的 Hint
,尤其是阅读 ls.c
的提示,会发现,其实这个代码跟 ls.c
的代码相差不大。
这里需要注意题中的两个要求:
- 递归寻找文件
- 不要递归进入”.”/”..”
添加文件 user/find.c
代码如下:
xargs(moderate)
开始动手前,先查清楚 xargs
命令的作用是什么。
xargs
常与管道符号|
一起使用,我们知道,管道的作用是将前一个命令的输出变为下一个命令的输入(一些粗糙的解释),但是管道存在一些无法完成的命令,这里使用 cat
命令来举例:
cat
命令可以接收文件名作为参数,执行后会显示出文件的内容。但是 cat
命令不能直接从标准输入接收参数:
这是因为:
- 管道可以实现:将前面的标准输出作为后面的“标准输入”
- 管道无法实现:将前面的标准输出作为后面的“命令参数”
因此需要使用 xargs
来讲前面的标准输出作为后面的命令参数而非标准输入,即,将标准输入作为其指定命令的参数。
添加文件 user/xargs.c
代码如下:
所有任务都完成后,记得在 Makefile
中添加 $U/_xxxx \$
,xxxx 为调用名称,也可以每写一个就添加一个,这样方便调试。
最终成绩
输入 make grade
来获得最终成绩。
(要添加一个 time.txt
文件才能拿满分,time.txt
内容只要一个整数,表示做完这个实验用了几个小时)
最后,输入
不需要 push
= =。