zoniony / zoniony.github.io

blog
1 stars 0 forks source link

6.S081 lab1 Xv6 and Unix utilities #4

Open zoniony opened 4 years ago

zoniony commented 4 years ago

6.S081自闭笔记

Lab1: Xv6 and Unix utilities

环境问题

Ubuntu19.10 libvirglrenderer.so.0版本过新导致qemu-system-riscv64无法运行

qemu-system-riscv64: symbol lookup error: /lib/x86_64-linux-gnu/libvirglrenderer.so.0: undefined symbol: drmPrimeHandleToFD

而且18.04也有问题,所以直接自己把qemu和riscv64给编译了,文件很大,下载编译需要很久

没代理网速不好建议直接放弃

LL7gm1

sleep

最简单的 学会如何修改内核代码 就是让你写代码 系统调用都写好了 让你封装一下 并且了解知识点 并且提出了一些规范

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

int main(int argc, char *argv[]) {

    //If the user forgets to pass an argument
    //sleep should print an error message.
    if (argc < 2) {
        fprintf(2, "plz input args\n");
        exit();
    }

    //can't be negative
    uint64 time = atoi(argv[1]);
    sleep(time);
    exit();
}

pingpong

通过pipe实现两个process的双向传递

pipe()函数实际上创建了两个文件描述符fd 而子进程中会同样创建 由此可以进程进程间的传递

如果单向传递需要一组Pipe 而双向传递需要两组pipe

试验过一组不能实现双线传递

ZXQMQ8

图片参考https://blog.csdn.net/oguro/article/details/53841949

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

int main(int argc, int **argv) {

    char buf[16];
    int parent_fd[2],child_fd[2];
    int pid;

    //don't want to judge argc
    if (argc > 1) {
        fprintf(2, "don't input redundant parameter. ok?\n");
        exit();
    }

    pipe(parent_fd);
    pipe(child_fd);

    pid = fork();
    if (pid < 0) {
        fprintf(2,"fail to fork (\n");    

    } else if(pid == 0) {
        close(parent_fd[1]);
        close(child_fd[0]);
        read(parent_fd[0],buf,4);
        printf("%d received %s\n",getpid(),buf);
        write(child_fd[1], "pong", 4);

    } else {
        close(parent_fd[0]);
        close(child_fd[1]);
        write(parent_fd[1], "ping", 4);
        read(child_fd[0],buf,4);
        printf("%d received %s\n",getpid(),buf);
    }
    exit();
}

prims

并发CSP模型communicating sequential processes 看不懂 自闭中

所以呢?这和并发CSP模型有什么关系= = 现在认为并没啥关系

更像用进程模拟递归 而且代码还写的贼难受

网上的有关CSP的资料全是go语言goroutine

MekPkP

图源:https://zhuanlan.zhihu.com/p/64823525

pipe是两个进程通讯的手段,而如上图依次传递。

而根据pingpong可知,进程的双向传递需要一组pipe

记得printf要放对位置 不然最后一次会把未定义地址的输出出来

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

void counter(int fd[]) {
    for(int i = 2;i < 34;i++){
        write(fd[1], &i, sizeof(i));
    }
    close(fd[1]);
}

void primeFilter(int fd[], int fds[], int prime) {

    int buf;
    while(read(fd[0], &buf, sizeof(buf))){
        if(buf % prime != 0 ){
            write(fds[1], &buf, sizeof(buf));
        }
    }
    close(fds[1]);
}

int output(int fd[]) {

    int buf;
    if (read(fd[0], &buf, sizeof(buf))) {
        printf("prime %d\n", buf);
    }
    return buf;
}

void preimSieve(int fd[]) {

    int fds[2];
    int prime,pid;

    //close write pipe
    //out prime
    close(fd[1]);

    //loop
    pipe(fds);
    pid = fork();
    prime = output(fd);
    if (pid < 0) {
        fprintf(2,"fail to fork");
        exit();
    } else if(pid) {
        close(fds[0]);
        primeFilter(fd,fds,prime);
    } else {
        preimSieve(fds);
    }
}

int main(int argc, int *argv[]) {

    int fd[2],pid;

    pipe(fd);
    pid = fork();

    if(pid < 0){
        fprintf(2,"fail to fork (\n");
        exit();
    } else if(pid) {
        close(fd[0]);
        counter(fd);
    } else{
        preimSieve(fd);
    }
    exit();
}

find

xargs