首页 > 其他分享 >MIT6.S081 Lab1

MIT6.S081 Lab1

时间:2024-06-04 14:22:22浏览次数:12  
标签:PIPE MIT6 buf char int Lab1 fd include S081

写在开头

6.S081/2021/Fall
当刚开始做这个实验的时候,我好像又陷入了一个误区,在实现Sleep的时候,我想了解Sleep到底是怎么完成运行的,浪费了一些时间,也没搞懂。
浪费了一段时间之后,我突然意识到:我并不熟悉MakeFile。
不熟悉MakeFile,我不可能去理解这个xv6是怎么运行的。
并且我的目的是去完成这个课程,并不是去了解xv6的运行过程。
如果我完成了这个课程,有了一个系统性的认识之后,到时候我再去了解这些问题。
可能以我现在的能力解决不了这个问题,并且会大大降低我做Lab的积极性。
不如一步一步的把Lab搞好,最后完成所有Lab之后再去研究(或者中途有些Lab会了解到这些知识)

总而言之就是一句话:先把既定的目标做好,做好目标之后会提高积极性,进入良性循环。难题之后再解决,避免降低积极性,陷入恶性循环。

希望自己今年能把这个Lab做完,不要不要半途而废。

Lab1 的主要工作是实现五个工具:Sleep、PingPong、Primes、Find、Xargs

Lab1

Sleep

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
int main(int argc, char *args[])
{
    if (argc <= 1)
    {
        fprintf(2, "you need to give sleep time!\n");
        exit(1);
    }
    sleep(atoi(args[1]));
    exit(0);
}

PingPong

开始以为xv6的printf只能传char * 不能传%d 这种,所以写的有些臃肿了

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#define PIPE_WRITE 1
#define PIPE_READ 0
#define EOF 0
#define WAIT (int *)0
#define CHILD 0
int main(int argv, char *args[])
{
    int p[2];
    pipe(p);
    int pid = fork();
    char *buf[10];
    if (pid == CHILD)
    {
        int child = getpid();
        int n = read(p[PIPE_READ], buf, sizeof buf);
        char arr[10];
        int now = 0;
        while (child)
        {
            arr[now] = '0' + child % 10;
            child /= 10;
        }
        printf(arr);
        printf(": received ping\n");
        write(p[PIPE_WRITE], buf, n);
        close(p[PIPE_READ]);
        close(p[PIPE_WRITE]);
        exit(0);
    }
    else
    {
        pid = getpid();
        write(p[PIPE_WRITE], "A", 1);
        int status;
        wait(&status);
        read(p[PIPE_READ], buf, sizeof buf);
        char arr[10];
        int now = 0;
        while (pid)
        {
            arr[now] = '0' + pid % 10;
            pid /= 10;
        }
        printf(arr);
        printf(": received pong\n");
        close(p[PIPE_READ]);
        close(p[PIPE_WRITE]);
    }
    exit(0);
}

Primes

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"

#define PIPE_WRITE 1
#define PIPE_READ 0
#define EOF 0
#define WAIT (int *)0
#define CHILD 0

void primes(int fd[2])
{
    int prime;
    close(fd[PIPE_WRITE]);
    if (read(fd[PIPE_READ], &prime, sizeof(int)) == EOF)
    {
        exit(0);
    }
    // printf("primes %d ", getpid());
    printf("prime %d\n", prime);
    int pp[2];
    pipe(pp);
    int ProcessId = fork();
    if (ProcessId == CHILD)
    {
        primes(pp);
        exit(0);
    }
    else
    {
        int now;
        close(pp[PIPE_READ]);
        while (read(fd[PIPE_READ], &now, sizeof(int)) != EOF)
        {
            int cur = now;
            if (cur % prime != 0)
                write(pp[PIPE_WRITE], &cur, sizeof(int));
        }
        close(pp[PIPE_WRITE]);
        close(fd[PIPE_READ]);
        wait(WAIT);
        exit(0);
    }
}

int main()
{
    int fd[2];
    pipe(fd);
    int pid = fork();
    if (pid == CHILD)
    {
        primes(fd);
        exit(0);
    }
    for (int i = 2; i <= 35; i++)
    {
        write(fd[PIPE_WRITE], &i, sizeof(int));
    }
    close(fd[PIPE_READ]);
    close(fd[PIPE_WRITE]);
    wait(WAIT);
    exit(0);
}

Find

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/fs.h"

char *fmt(char *path) {
  static char buf[DIRSIZ + 1];
  char *p;

  // Find first character after last slash.
  for (p = path + strlen(path); p >= path && *p != '/'; p--);
  p++;

  // Return blank-padded name.
  if (strlen(p) >= DIRSIZ) return p;
  memmove(buf, p, strlen(p));
  buf[strlen(p)] = 0;  // end of file name
  return buf;
}
void find(char *path, char *pattern) {
  int fd;
  struct stat st;
  struct dirent de;
  char buf[512], *p;
  char *fmtname = fmt(path);  // current dir/file name (exclude parents)
  if ((fd = open(path, 0)) < 0) {
    fprintf(2, "ls: cannot open %s\n", path);
    return;
  }
  if (fstat(fd, &st) < 0) {
    fprintf(2, "ls: cannot stat %s\n", path);
    close(fd);
    return;
  }
  switch (st.type)

Xargs

最开始没有想到怎么读入数据,是看到别人的answer之后才想到使用while(read(1))

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/fs.h"

#define READ 0
#define WRITE 1
#define MAXARG 32

int main(int argv, char *args[])
{
    char *argument[MAXARG];
    int index = 0;
    for (int i = 1; i < argv; i++)
    {
        argument[index++] = args[i];
    }
    char buf[512];
    char *p = buf;
    // test "echo 1\n2 | xarg echo line"
    // int fd[2];
    // pipe(fd);
    // char *test = "1\n2";
    // write(fd[WRITE], test, sizeof test);
    // close(fd[WRITE]);
    while (read(READ, p, 1) == 1)
    {
        if ((*p) != '\n')
        {
            p++;
        }
        else
        {
            *p = 0;
            argument[index] = buf;
            int pid = fork();
            if (pid == 0)
            {
                exec(argument[0], argument);
                fprintf(2, "error");
                exit(1);
            }
            wait(0);
            p = buf;
        }
    }
    if (p != buf)
    {
        *p = 0;
        argument[index] = buf;
        int pid = fork();
        if (pid == 0)
        {
            exec(argument[0], argument);
            fprintf(2, "error");
            exit(1);
        }
        wait(0);
    }
    exit(0);
}

标签:PIPE,MIT6,buf,char,int,Lab1,fd,include,S081
From: https://www.cnblogs.com/x1uc/p/18230671

相关文章

  • 6.s081通关小结
    6.s081通关小结终于是完成6.s081的所有lab了,感慨万千。已经忘了第一次听说这个lab是在什么时候了,只是模模糊糊地感觉是大三。那时的我第一次找到了刷题之外的新方向。但囿于小镇做题家对计算机认识的滞后性,什么Linux、Ubuntu之类的新系统如同一座大山横亘在我于s081之间。又或......
  • mit6.828笔记 - lab5(上)- Spawn and Shell
    SpawningProcess有了文件系统了,我们终于可以方便地读取磁盘中的文件了。到目前为止,我们创建进程的方法一直都是在编译内核的时候将程序链接到数据段,在i386_init通过ENV_CREATE宏创建。现在我们应该考虑通过文件系统直接将用户程序从硬盘中读取出来,spawn就是这样的东西。s......
  • spanner,mit6.824论文解读
    为什么选择这篇论文(GoogleSpanner,OSDI2012)?宽域分布式事务的罕见示例。非常理想。但是二阶段提交被视为太慢并且容易阻塞。宽域同步复制的罕见示例。巧妙的想法:通过Paxos进行的两阶段提交。同步时间用于快速只读事务。在Google内部广泛使用。动机用例是什么?......
  • mit6.828笔记 - lab4 Part C:抢占式多任务和进程间通信(IPC)
    PartC:抢占式多任务和进程间通信(IPClab4到目前为止,我们能够启动多个CPU,让多个CPU同时处理多个进程。实现了中断处理,并且实现了用户级页面故障机制以及写时复制fork。但是,我们的进程调度不是抢占式的,现在每个进程只有在发生中断的时候,才会被调度(调用shed_yeild),这样就有可能会有......
  • mit6.828笔记 - lab4 Part B:写时复制Fork
    PartBCopy-on-WriteForkUnix提供 fork() 系统调用作为主要的进程创建基元。fork()系统调用复制调用进程(父进程)的地址空间,创建一个新进程(子进程)。不过,在调用 fork() 之后,子进程往往会立即调用 exec(),用新程序替换子进程的内存。例如,shell通常就是这么做的。在这种情况......
  • MIT 6.S081 学习笔记 -- page tables
    Chapter3Pagetable1.FromUserperspetive,howVAmapstoPA?lab1:printpagetableforpid==1, PR: https://github.com/nipperhou/xv6-riscv/commit/eb8e0008c019cfa0f3687989a90a63a7d45bde6fOutput: ```xv6kernelisbootingtrampoline:0x00000000800070......
  • mit6.828笔记 - lab3 Part A:用户进程和异常处理
    简单回顾在开始lab3的学习之前,我们先简单回顾下到目前为止,我们的内核能做了什么:lab1中,我们学习了PC启动的过程,看到BIOS将我们编写的bootloader载入内存,然后通过bootloader将内核载入内存。同时,使用了一个写死的临时页表(entry_pgdir)完成了简单的地址映射;我们的内核最后执......
  • mit6.828笔记 - lab3 Part B:页面故障、断点异常和系统调用
    PartB页面故障、断点异常和系统调用虽然说,我们故事的主线是让JOS能够加载、并运行user/hello.c编译出来的镜像文件。虽然说,经过PartA最后几节,我们初步实现了异常处理的基础设施。但是对于操作系统来说,还远远不够,比如说那个trap_dispatch还没完成。所以在回到故事主线之......
  • MIT6S081课程笔记
    MIT6S081课程笔记mit6s081lecturenotesCreated:2023-06-05T20:26+08:00Published:2024-05-12T12:13+08:00Categories:OperatingSystem关于这门课程使用到的资料:schedule:https://pdos.csail.mit.edu/6.S081/2020/schedule.htmlschedule可以认为提供了资源(如pdf、......
  • mit6.828 - lab2笔记
    目标:重点学习内存管理的相关知识,包括内存布局、页表结构、页映射任务:完成内存管理的相关代码lab2中,完全可以跟着实验手册的节奏走,逐步完善内存管理的代码。环境准备:实验2包含以下新的源文件:inc/memlayout.hkern/pmap.ckern/pmap.hkern/kclock.hkern/kclock.cmemlay......