6.S081-Lab1
发布于 2022218|更新于 202239|遵循 CC BY-NC-SA 4.0 许可

折磨一个月之后总算把Lab1糊出来了,由于是第一次接触各种system call,实际实现的时候反复翻了几遍文档。最后还是要借助其他前辈留下来的实验记录。折腾之后算是有些收获,比如子进程创建、管道的运用、标准I/O的理解之类。

下面是每个函数的思路。

Sleep

实验文档给了提示,先看操作手册xv6 book。这个函数主要要用sleep来实现。

同时文档建议参考已有的函数实现来写,所以照猫画虎,函数实现相对简单。要注意的是对于参数数量的判断,以及需要将参数中的字符串格式数字转换成整型。

Pingpong

一开始理解错了意思,事实上题目只是要求传任意一个字节的数据就可以了,pingpong只是硬编码的输出内容。

这个函数目的有两个。第一个是要了解fork创建子进程,通俗来说,从fork()开始进程就被分为了父子进程,两个进程中的内容相同,但可以根据fork()返回的值是否为0分别操作两个进程要做的任务。

第二个是理解如何利用pipe在父子进程中传递消息。由于fork之后父子进程都会各自获得一对相同的文件描述符fd,因此只需要在A侧write,B侧read即可完成信息传递。

getpid没什么好说的,就是一个获取pid的函数。

Primes

主要是对forkpipe运用的考察。

其中质数的判断思想参照了文档中提供的文章(文档中的文章链接),因此递归函数prime需要依次传入若干整数到下一个函数中,这里用pipefork构成的pipeline来传递。

prime函数里,通过fork创建出两个进程。其中父进程处理左端管道传来的数字并判断是否需要传进下一个管道,子进程进行递归操作。

由于Xv6的限制,在fork的时候复制出的文件描述符需要及时清除(close),否则程序会因为资源耗尽被卡住。

Find

主要是运用open,同时认识到两个结构体——statdirent,前者可以方便我们了解该“文件”是什么类型(File/Directory/Device),后者包含了“文件”名字,方便匹配。

比起Primes,Find的实现要简单多了。主要参考了ls.c中的内容,并进行递归查询,注意要忽略...

Xargs

这个函数要求利用|将左侧的输出作为参数传给右边,其中最大的问题是如何接住|左边的输出?

通过重新阅读手册我认识到左侧的输出都是在标准I/O中完成的,因此只要read(0, ch, 1)就可以获取一个字符的内容。

因此首先将右侧要执行的参数放进新的参数表params[]中,然后对左侧的参数内容进行循环,依次把识别到的参数放进params[],其中read获得的字符内容通过空格划分。每遇到一次换行\n,就执行一次右侧命令,然后清空参数表,进行下一个循环。

一些注意点文档里都有提示,照做就没有问题,执行sh < xargstest.sh能够正确输出结果。

References

参考了两个仓库代码:

参考了一篇实验记录:

Lab1对我来说有不小的挑战性,没有他们的文章参考我大概是做不出来的。

最后是我的代码存档:palemoons/xv6-labs-2020

Comments