Lab1

启动xv6(难度:Easy)

https://lmx.gitbook.io/mit-6.s081/

sleep(难度:Easy)

YOUR JOB

实现xv6的UNIX程序sleep:您的sleep应该暂停到用户指定的计时数。一个滴答(tick)是由xv6内核定义的时间概念,即来自定时器芯片的两个中断之间的时间。您的解决方案应该在文件*user/sleep.c*中

// user/ulib.c
int
atoi(const char *s)
{
  int n;

  n = 0;
  while('0' <= *s && *s <= '9')
    n = n*10 + *s++ - '0';
  return n;
}

// kernel/sysproc.c
uint64
sys_sleep(void)
{
  int n;
  uint ticks0;

  if(argint(0, &n) < 0)
    return -1;
  acquire(&tickslock);
  ticks0 = ticks;
  while(ticks - ticks0 < n){
    if(myproc()->killed){
      release(&tickslock);
      return -1;
    }
    sleep(&ticks, &tickslock);
  }
  release(&tickslock);
  return 0;
}
// kernel/sysproc.h
#define SYS_sleep  13

// user/user.h提供了sleep的声明以便其他程序调用,用汇编程序编写的user/usys.S可以帮助sleep从用户区跳转到内核区。

实现代码:

测试:

pingpong(难度:Easy)

YOUR JOB

编写一个使用UNIX系统调用的程序来在两个进程之间“ping-pong”一个字节,请使用两个管道,每个方向一个。父进程应该向子进程发送一个字节;子进程应该打印“<pid>: received ping”,其中<pid>是进程ID,并在管道中写入字节发送给父进程,然后退出;父级应该从读取从子进程而来的字节,打印“<pid>: received pong”,然后退出。您的解决方案应该在文件*user/pingpong.c*中。

请使用两个管道

不用两个管道会报莫名其妙的错误(我还是看不透pipe)

p[0] 是管道的读端,p[1]是管道的写端

测试:

Primes(素数,难度:Moderate/Hard)

tasks:

YOUR JOB

使用管道编写prime sieve(筛选素数)的并发版本。这个想法是由Unix管道的发明者Doug McIlroy提出的。请查看这个网站arrow-up-right,该网页中间的图片和周围的文字解释了如何做到这一点。您的解决方案应该在*user/primes.c*文件中。

感觉上面那题会了的话,这题比上一题简单

测试:

关于上面的主线程为什么要exit,有一个比较坑的地方:

看下面程序:

  • 首先fork出来的是进程,父和子的index是不相通的

  • 当子进程的index超过3,子进程就会结束

  • 这里意思就是在3之前主进程都在wait(),3的时候子进程会exit,这时候index为2的是它的父进程,而这个2的进程同时也是1的子进程,所以那个最初的进程一直都不会退出,然后一直卡在index为2的那个线程那里,一直fork。

  • 当到子进程的index为2时,他成为父进程,fork一个子进程,子进程复制变量,index=2,index++ 变成3,然后该子进程退出。但是此时父进程的index是2,它还会继续进入循环,又fork一个子进程,子进程再复制变量,然后自增,周而复始...这样就一直卡在3这里了

  • 所以必须有个 exit(0),在他完成所有的子任务第一遍时,也就是打印第一遍3的时候就退出程序,这样就完成了任务了

  • 再看上面的通关代码,也是如此,如果没有exit(0),就会一直卡在输出31的地方,因为它也会在那时候一直fork一个子进程,然后退出然后再fork再退出再fork。

  • 反正就是要记得,fork会复制变量,但是父子的变量是不同的,子进程的这个变量改变不会影响父进程的值。也就是fork是变量复制但不共享

find(难度:Moderate)

YOUR JOB

写一个简化版本的UNIX的find程序:查找目录树中具有特定名称的所有文件,你的解决方案应该放在*user/find.c*

刚开始不知道他要实现啥,写完只通过了第一个test,但是输出显示第二个test我失败是miss了一些输出,那我按它的输入去debug,发现我没有递归进子目录....蠢得可以,又改了一下才ok,所以还是要好好思考...

test:

不知道有没有更快得实现,期待一手

xargs (难度: Moderate)

前面的find实现有坑,我的find理解和出题人的find理解不同

在ubuntu下的 find . b 不是先 find . 再 find b吗,我试了一下就是这样啊,但是这道题目要求find . b 是在 . 路径下寻找 b 的目录,这让我不得不回去改了一下find的代码,先贴上改完的find,被迫无奈:

通过实现:

test:

Last updated