6.S081「Xv6 and Unix utilities」

  • insorker
  • 2022/2/21

Hello

新学期,新气象,祝看到这篇文章的人一生不患腱鞘炎。

Introduction

This lab will familiarize you with xv6 and its system calls.

做了一遍所有题目,主要考察的还是你对系统调用的理解,虽然后面的东西还没学,但我目前猜测是先完善shell和gdb,做好调试工作,然后再深入操作系统。

因为和南大的PA是一起做的,所以取长补短还算有了一些心得【当然是取他人之长补我自己的短】。这里做一些推荐:

  • ctags:很好用的vim插件
  • CSAPP:学一遍还是很有帮助的

Problems

突然想起来的声明:因为只是练习题,所以不做异常判断了

1. sleep (easy)

简单题,主要就是让你熟悉一下做题大概的流程

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"static char sleep_error[] = "Sleep Error: No Input";int
main(int argc, char *argv[])
{if (argc == 1) {write(1, sleep_error, strlen(sleep_error));exit(1);}sleep(atoi(argv[1]));exit(0);
}

2. pingpong (easy)

像乒乓球一样,想想一个来回的过程。

题目没说发送什么东西,所以重点在于你发送的顺序:

  1. parent send byte
  2. parent wait
  3. child read and print
  4. child send byte
  5. child exit
  6. parent read and print

然后代码就很简单了

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"static char pipe_error[] = "Pipe Error";int
main(int argc, char *argv[])
{int p[2], childpid;char psend = 'f', ssend = 's';char precv, srecv;if (pipe(p) == -1) {write(1, pipe_error, sizeof(pipe_error));exit(-1);}childpid = fork();if (childpid == 0) {read(p[0], &srecv, sizeof(srecv));printf("%d: received ping\n", getpid());write(p[1], &ssend, sizeof(ssend));}else {write(p[1], &psend, sizeof(&psend));wait(0);read(p[0], &precv, sizeof(precv));printf("%d: received pong\n", getpid());close(p[0]);close(p[1]);}exit(0);
}

3. primes (moderate)/(hard)

这题确实算难题,但又其实很简单。我卡了一会的原因是我知道要关掉所有输出,但还是忘了关掉父线程的输出。

解释一下题目:

题目也说了,去这个页面csp的中间那张图的前后文理解一下题目,原页面的伪代码也写的很清楚,思路还是有的。

看完了后整体上第一感觉肯定是递归,但是写迭代也不是不能写(我就是),跳出条件就是遍历完34个数字。然后想的就是如何实现,因为具有传递性,所以对于某个中间部分,最少需要两个管道,一个从上一个部分读取,一个向下一个部分输出,因为时间上不能确定谁先谁后,所以必须要两个。

补充一个关于read系统调用的知识:

教程第16页中间有一段话

If no data is available, a read on a pipe waits for either data to be written or for all file descriptors referring to the write end to be closed; in the latter case, read will return 0, just as if the end of a data file had been reached.

意思就是read结束一个条件是EOF,另一个是所有输入关闭,所以这道题要我们手动close所有输入文件描述符

整理一下我们的思路,假设我们现在fork出来了一个子进程,他需要做什么:

  1. 父进程向他发送数字,从左边的管道读取,第一个数字是质数
  2. 本身需要读取所有数字,不能被质数整除的数字write到右边的管道
  3. 读取完成后,关闭读取,创建一个子进程,从操作1开始重复
  4. wait and exit

写成代码就是这样紫

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"int
main(int argc, char *argv[])
{int pl[2], pr[2];pipe(pr);for (int i = 2; i <= 35; i ++ )write(pr[1], &i, sizeof(i));while (1) {int num = -1, prime;pl[0] = pr[0], close(pr[1]);if (fork() == 0) {pipe(pr);read(pl[0], &prime, sizeof(prime));printf("prime %d\n", prime);/* printf("num"); */while (read(pl[0], &num, sizeof(num))) {/* printf(" %d", num); */if (num % prime != 0)write(pr[1], &num, sizeof(num));}/* printf("\n"); */close(pl[0]);if (num == -1) {close(pr[0]);exit(0);}}else {wait(0);exit(0);}}
}

4. find (moderate)

这里需要注意的是find可能和我们平常用的方法不一样,这里的使用时find [path] [file]按照这个思路编程就行了

然后参考ls.c,照着抄就很简单了(不是

另外要记得特判一下".“和”…"

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/fs.h"#define ALERT(x) printf("wrong => %d\n", x)char*
fmtname(char *path)
{char *p;for (p = path + strlen(path); p >= path && *p != '/'; p -- );p ++ ;return p;
}void
find(char *path, char *file)
{char buf[512], *p;int fd;struct stat st;struct dirent de;if ((fd = open(path, 0)) < 0) {ALERT(3); return;}if (fstat(fd, &st) < 0) {ALERT(4); close(fd); return;}switch (st.type) {case T_FILE:if (strcmp(fmtname(path), file) == 0)printf("%s\n", path);break;case T_DIR:strcpy(buf, path);p = buf + strlen(buf);*p++ = '/';while (read(fd, &de, sizeof(de)) == sizeof(de)) {if (de.inum == 0)continue;memmove(p, de.name, DIRSIZ);if (strcmp(de.name, ".") == 0)continue;else if (strcmp(de.name, "..") == 0)continue;p[DIRSIZ] = 0;find(buf, file);}break;}close(fd);
}int
main(int argc, char *argv[])
{if (argc < 3) {ALERT(0);exit(1);}for (int i = 2; i < argc; i ++ )find(argv[1], argv[i]);exit(0);
}

5. xargs (moderate)

这题也不难,内存分配好就没问题了,看了另外一个人的解说,这里粘贴过来

原文链接

说实话,做实验之前我都不知道 xargs 是干嘛用的。所以得先了解一下 xargs 的作用,参考阮一峰的博客

其中,第二段的一句话非常关键;

xargs命令的作用,是将标准输入转为命令行参数 所以我们实验的整体思路,就是读入标准输入,转成多个命令行参数。

只要把握住这句话,这个实验代码就呼之欲出了。

其实这里我还有个疑问,malloc分配的内存是什么时候被释放的?

因为调用了exec,所以没办法手动释放,那么不就造成内存泄漏了吗?

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/param.h"int
main(int argc, char *argv[])
{char *args[MAXARG], *p;int args_idx = 0;for (int i = 1; i < argc; i ++ ) {args[args_idx] = (char *)malloc(sizeof(argv[i]));memmove(args[args_idx], argv[i], sizeof(argv[i]));args_idx ++ ;}args[args_idx] = (char *)malloc(512 * sizeof(char));p = args[args_idx ++ ];while (read(0, p, sizeof(char))) {if (*p == ' ' || *p == '\n') {*p = 0;if (*p == '\n')break;args[args_idx] = (char *)malloc(512 * sizeof(char));p = args[args_idx ++ ];}else p ++ ;}/* for (int i = 0; i < args_idx; i ++ ) *//*     printf("%s\n", args[i]); */exec(args[0], args);exit(0);
}

The End

开始?还是结束?

下一站: Lab pgtbl: Page tables

6.S081「Xv6 and Unix utilities」相关推荐

  1. 操作系统实验Lab 1:Xv6 and Unix utilities(MIT 6.S081 FALL 2020)

    Lab 1 Xv6 and Unix utilities 实验要求链接 Boot xv6 (easy) 实验目的 切换到 xv6-labs-2020 代码的 util 分支,并利用 QEMU 模拟器启 ...

  2. Lab: Xv6 and Unix utilities sleeppingpong

    实验环境 VMware Ubuntu20.04 + xv6-labs-2021 1. 实验内容与要求 阅读Lab: Xv6 and Unix utilities中的sleep,pingpong两个任务 ...

  3. xv6---Lab1: Xv6 and Unix utilities

    目录 参考资料: 1.1进程和内存 1.2 I/O 和文件描述符 1.3管道 源码: 调试环境搭建 sleep PingPong primes find xargs 参考资料: Lab: Xv6 an ...

  4. 操作系统lab:Xv6 and Unix utilities

    lab1:Xv6 and Unix utilities 实验的主要内容,xv6的系统调用以及实现一些基础的shell操作.实验链接 实验总结 xv6环境配置,教程.注意事项,在配置的过程中出现问题,i ...

  5. 6.S081-Lab: Xv6 and Unix utilities 操作系统实验

    学习操作系统的时候,买了一本人民邮电出版社的-Operating Systems: Three Easy Pieces 中译版(操作系统导论). 从书中学到了很多关于操作系统的思想,出现一个问题,思考 ...

  6. Lab01:Xv6 and Unix utilities

    实验测试方法 实验的测试方法主要有2个: 进入到Xv6系统中,执行相应的命令 使用实验提供的评分测试 对于单个实验,可以使用 make GRADEFLAGS=application grade其中ap ...

  7. xv6学习笔记——Lab: Xv6 and Unix utilities

    文章目录 前言 一.进程与内存 1.1 fork() 1.2 wait() 1.3 exit() 1.4 exec() 前言 最近在学习MIT经典的操作系统课程--xv6操作系统,之前在本科生期间同样 ...

  8. 「从 Windows 到 macOS」快速理顺两大系统之间的差异

    虽然从熟悉的平台转移到另一个陌生平台的做法一般不会经常发生,但如果你已经决定从 Windows 转移到 macOS,那么在踏入「新世界」的大门之前,或许这份「从 Windows 到 macOS」的入门 ...

  9. 操作系统MIT6.S081:[xv6参考手册第4章]->Trap与系统调用

    本系列文章为MIT6.S081的学习笔记,包含了参考手册.课程.实验三部分的内容,前面的系列文章链接如下 操作系统MIT6.S081:[xv6参考手册第1章]->操作系统接口 操作系统MIT6. ...

最新文章

  1. MSHA x Chaos 容灾高可用实践
  2. win8计算机安全模式,安全模式,详细教您Win8怎么进入安全模式
  3. HTML5如何控制暂停播放停止
  4. 轻触开源(一)-Java泛型Type类型的应用和实践
  5. leetcode —— 33. 搜索旋转排序数组
  6. C++基于TCP和UDP的socket通信
  7. iOS 数组模型排序
  8. 54. mysqli 扩展库
  9. JAVA集合系列(1):集合的整体框架
  10. 怎么用计算机打出音乐符号,音乐符号怎么打(教你word文档音乐符号怎么打)...
  11. java数据流编辑 kylo,Kylo 在个推信息流推荐引擎中的使用及扩展
  12. 华为手机流量日显示无服务器,华为手机开启了数据流量却不能上网怎么办
  13. 怎样清理软件卸载残留文件和系统垃圾
  14. 基于Springboot+Vue开发前后端端分离农产品进销存系统
  15. wx.canIUse
  16. Centos初学者需要会的几种命令(2)
  17. 中国人工智能学会通讯——AI时代的若干伦理问题及策略 1.1人工智能时代正在加速到来,算法决策开始兴起...
  18. eclipse升级adt
  19. sql脚本语言中的循环语句介绍
  20. 如何在显示图片缩略图时不挤压拉伸图片

热门文章

  1. mysql:ERROR 1366 (HY000): Incorrect string value: ‘\x80\xE6\x96\xB0‘ for column ‘name‘ at row 1
  2. PLC/DCS系统常见的干扰现象及判断方法
  3. 视频超分辨率论文笔记
  4. ARM体系结构(四)
  5. Leetcode 297:二叉树的序列化与反序列化(超详细的解法!!!)
  6. 蓝牙耳机什么牌子好?推荐四个高品质蓝牙耳机品牌
  7. ise9.2中的三模冗余设计步骤
  8. Hadoop入门学习笔记-第五天(hadoop-hive安装部署与配置笔记)
  9. c语言 异或结合律,异或运算
  10. 云南大学计算机专业双一流排名,2019年云南双一流大学最终名单_双一流大学排名...