• Lab: Xv6 and Unix utilities


    实验链接

    https://pdos.csail.mit.edu/6.S081/2020/labs/util.html

    Sleep

    代码如下:

    #include "kernel/types.h"
    #include "kernel/stat.h"
    #include "user/user.h"
    
    int
    main(int argc, char *argv[])
    {
    
      if(argc < 2){
        fprintf(2, "Usage:  sleep number seconds\n");
        exit(1);
      }
    
      int sleep_sec = atoi(argv[1]);
      sleep(sleep_sec);
      exit(0);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    Pingpong

    题意如下:

    首先介绍一下管道:

    1. 管道只能从一段写入,另一端读出;
    2. 管道不是普通的文件,他存在于内存中,不存在于某个文件系统;
    3. 管道没有名字,只能在具有公共祖先的进程中使用;
    4. 半双工,同一时刻,只能在一个方向有数据流动。

    代码如下:

    
    #include "kernel/types.h"
    #include "kernel/stat.h"
    #include "user/user.h"
    
    int
    main(int argc, char *argv[])
    {
    
      int pipefd[2];
      int cpid;
      char buf = 'c';
      if (pipe(pipefd) == -1) {
          printf("pipe error\n");
          exit(1);
      }
    
      cpid = fork();
      if (cpid == -1) {
          printf("fork error\n");
          exit(1);
      }
    
      if (cpid == 0) { // child process
          read(pipefd[0], &buf, 1);
          cpid = getpid();
          printf("%d: received ping\n", cpid);
          write(pipefd[1], &buf, 1);
    
      } else {
          write(pipefd[1], &buf, 1);
          // if we do not sleep here, the parent would read from the pipe, and the child would not be able to read from the pipe
          // if you do not want to sleep here, you should use two pipes instead of one
          sleep(1);
          read(pipefd[0], &buf, 1);
          cpid = getpid();
          printf("%d: received pong\n", cpid);
      }
      exit(0);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    Primes

    题意如下:

    题目需要计算2至35之间的所有质数,步骤如下:

    1. 每个进程从自己的父进程读数据(第一个进程除外,因为其没有父进程),经过处理之后,将结果写到自己的孩子进程;
    2. 每个进程的处理过程如下:接收到的第一个数字必定为质数P,如果自己接收到数据能被P整除,那它肯定不是质数,则该数字不传给自己的孩子进程,否则,将其传给自己的孩子进程;
    3. 其实这和算法题中,计算指定区间的质数一样,先去除区间内所有能被2整除的数,在剩下的数字中再除去所有能被3整除的数,在剩下的数字中再除去所有能被5整除的数,依次类推。。。

    代码如下:

    #include "kernel/types.h"
    #include "kernel/stat.h"
    #include "user/user.h"
    
    
    void work(int parent_pipe[]) {
        close(parent_pipe[1]);
        int child_pipe[2];
    
        int base;
        if (read(parent_pipe[0], &base, 4) == 0) {
            exit(0);
        }
        printf("prime %d\n", base);
        if (pipe(child_pipe) == -1) {
            printf("pipe error\n");
            exit(0);
        }
    
        int cpid = fork();
        if (cpid == -1) {
            printf("fork error\n");
            exit(1);
        }
    
        if (cpid != 0) { // parent
            close(child_pipe[0]);
            while (1) {
                int recv = 0;
                int ret = read(parent_pipe[0], &recv, sizeof(int));
                if (ret == 0) {
                    break;
                }
                if (recv % base != 0) {
                    int send = recv;
                    write(child_pipe[1], &send, sizeof(int));
                }
            }
            close(parent_pipe[0]);
            close(child_pipe[1]);
            wait(0);
        } else {
            work(child_pipe);
        }
        exit(0);
    }
    
    int main(int argc, char *argv[]) {
        int pipefd[2];
        if (pipe(pipefd) == -1) {
            printf("pipe error\n");
            exit(1);
        }
    
        int cpid = fork();
        if (cpid == -1) {
            printf("fork error\n");
            exit(1);
        }
    
        if (cpid == 0) { // child process
            work(pipefd);
        } else {
            close(pipefd[0]);
            // the first process pipe write all numbers to the next pipe
            for (int i = 2; i <= 35; i++) {
                write(pipefd[1], &i, sizeof(int));
            }
            close(pipefd[1]);
            wait(0);
        }
        exit(0);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74

    find

    #include "kernel/types.h"
    #include "kernel/stat.h"
    #include "user/user.h"
    #include "kernel/fs.h"
    
    
    void get_files(const char* file_path, const char* file_name) {
        char buf[512], *p;
        int fd;
        struct dirent de;
        struct stat st;
    
        if((fd = open(file_path, 0)) < 0){
            fprintf(2, "find: cannot open %s\n", file_path);
            return;
        }
    
        if(fstat(fd, &st) < 0){
            fprintf(2, "find: cannot stat %s\n", file_path);
            close(fd);
            return;
        }
    
        switch(st.type) {
            case T_FILE:
                printf("Find a file instead of a path: %s\n", file_path);
                break;
    
            case T_DIR:
                if(strlen(file_path) + 1 + DIRSIZ + 1 > sizeof(buf)){
                    printf("find: path too long\n");
                    break;
                }
                strcpy(buf, file_path);
                p = buf+strlen(buf);
                *p++ = '/';
                while(read(fd, &de, sizeof(de)) == sizeof(de)){
                    if(de.inum == 0)
                        continue;
                    if (strcmp(de.name, ".") == 0 || strcmp(de.name, "..") == 0) {
                        continue;
                    }
                    memmove(p, de.name, DIRSIZ);
                    p[DIRSIZ] = 0;
                    if(stat(buf, &st) < 0){
                        printf("ls: cannot stat %s\n", buf);
                        continue;
                    }
                    // printf("find a file: %s\n", de.name);
                    if (st.type == T_DIR) {
                        get_files(buf, file_name);
                    } else if (st.type == T_FILE) {
                        if (strcmp(file_name, de.name) == 0) {
                            printf("%s\n", buf);
                        }
                    }
                }
                break;
        }
        close(fd);
    }
    
    int main(int argc, char *argv[])
    {
        if(argc < 3) {
            printf("Usage:  \n");
            exit(0);
        }
        char* file_path = argv[1];
        char* file_name = argv[2];
        get_files(file_path, file_name);
        exit(0);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74

    xargs

    代码如下:

    
    #include "kernel/types.h"
    #include "kernel/stat.h"
    #include "user/user.h"
    #include "kernel/fs.h"
    #include "kernel/param.h"
    
    int
    getcmd(char *buf, int nbuf)
    {
        memset(buf, 0, nbuf);
        gets(buf, nbuf);
        if(buf[0] == 0) // EOF
            return -1;
        return 0;
    }
    
    int main(int argc, char *argv[])
    {
        if(argc < 2) {
            printf("Usage: xargs \n");
            exit(0);
        }
    
        if (argc - 1 > MAXARG) {
            printf("Too many args. \n");
            exit(0);
        }
    
        char* cmd_args[MAXARG];
        int j = 0;
        for (int i = 1; i < argc; i++) {
            cmd_args[j] = malloc(512 * sizeof(char));
            memset(cmd_args[j], 0, 512 * sizeof(char));
            strcpy(cmd_args[j], argv[i]);
            j++;
        }
    
        char* cmd = argv[1];
        static char buf[100];
        while(getcmd(buf, sizeof(buf)) >= 0) {
            int len = strlen(buf) - 1;
            buf[len] = '\0';
            char pre = -1;
            int k = 0;
            for (int i = 0; i < len; i++) {
                if (buf[i] == ' ') {
                    if (pre == ' ') {
                        continue;
                    } else {
                        cmd_args[j][k] = 0;
                        j++;
                        k = 0;
    
                    }
                } else {
                    if (k == 0) {
                        cmd_args[j] = malloc(512 * sizeof(char));
                        memset(cmd_args[j], 0, 512 * sizeof(char));
                    }
                    cmd_args[j][k] = buf[i];
                    k++;
                }
                pre = buf[i];
            }
            if (fork() == 0) { // child process
                exec(cmd, cmd_args);
                fprintf(2, "exec %s failed\n", cmd);
                exit(0);
            } else {
                wait(0);
            }
        }
        wait(0);
        exit(0);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77

    课程推荐资料

    csp

    1. a tech talk at goole
    2. 2010 Google IO talk with Russ Cox

    github

    https://github.com/aerfalwl/mit-xv6-labs-2020.git

  • 相关阅读:
    【校招VIP】测试计划之loadrunner分析
    Flask对请求进行多个格式的响应
    vue3.4的更新,保证你看的明明白白
    微信小程序实战十四:小程序及APP端实现客服功能
    可观测性-可视化-Grafana 数据下钻
    如何在 Windows 10 上安装 Ubuntu 操作系统?
    西安健身房共享系统开发如何快速回笼资金?
    Spring Security—Servlet 应用架构
    【AI视野·今日Sound 声学论文速览 第十五期】Fri, 29 Sep 2023
    el-table 多表格弹窗嵌套数据显示异常错乱问题
  • 原文地址:https://blog.csdn.net/u014110320/article/details/125911259