【操作系统xv6】学习记录5--实验1 Lab: Xv6 and Unix utilities

news2024/11/26 8:32:59

ref:https://pdos.csail.mit.edu/6.828/2020/xv6.html

在这里插入图片描述

实验:Lab: Xv6 and Unix utilities

环境搭建

实验环境搭建:https://blog.csdn.net/qq_45512097/article/details/126741793
搭建了1天,大家自求多福吧,哎。~搞环境真是折磨人
anyway,我搞好了:
在这里插入图片描述

开整实验

内容1:sleep

创建user/sleep.c
在Makefile中UPROGS下添加$U/_sleep
编写sleep.c
运行测试程序grade-lab-util并且指明要测试的函数。如 grade-lab-util sleep

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

void main(int argc, char *argv[])
{
  if(argc != 2){
    // 2 输出到哪里,输出内容,
    fprintf(2,"usage:sleep <time> \n");
    exit(1);
  }
  int sec = atoi(argv[1]);
  sleep(sec);  
  //printf("usage:sleep %d \n",sec);
  exit(0);
}

修改makefile,只需要改这一个地方

在这里插入图片描述

验证命令,要退出qume才能执行,否则会报错,
这种时候单项验证sleep

./grade-lab-util sleep
justin@DESKTOP-NIK28BI:~/vc6/xv6-labs-2020$ ./grade-lab-util sleep
fatal: detected dubious ownership in repository at '/mnt/d/code/vc6/xv6-labs-2020'
To add an exception for this directory, call:

        git config --global --add safe.directory /mnt/d/code/vc6/xv6-labs-2020
make: 'kernel/kernel' is up to date.
== Test sleep, no arguments == fatal: detected dubious ownership in repository at '/mnt/d/code/vc6/xv6-labs-2020'
To add an exception for this directory, call:

        git config --global --add safe.directory /mnt/d/code/vc6/xv6-labs-2020
sleep, no arguments: OK (1.3s)
== Test sleep, returns == sleep, returns: OK (0.8s)
== Test sleep, makes syscall == sleep, makes syscall: OK (1.0s)

内容2:pingpong

Write a program that uses UNIX system calls to ‘‘ping-pong’’ a byte between two processes over a pair of pipes, one for each direction.
The parent should send a byte to the child;
the child should print “: received ping”, where is its process ID, write the byte on the pipe to the parent(这里没有指定具体写什么内容,什么都可以,只是作为标志,且这个标志不需要也不要打印,否则会影响测评), and exit;
the parent should read the byte from the child, print “: received pong”, and exit.
Your solution should be in the file user/pingpong.c.

#include "kernel/types.h"
#include "user/user.h"
#define RD 0 // pipe的read端
#define WR 1 // pipe的write端
int main(){
    char buf[10]; //缓冲区字符数组,存放传递的信息
    int fd_c2p[1]; // child->parent
    int fd_p2c[1]; // parent->child
    int ret1 = pipe(fd_c2p);
    int ret2 = pipe(fd_p2c);
    if(ret1==-1){
        printf("child->parent pipe");
        exit(1);
    }
    if(ret2==-1){
        printf("parent->child pipe");
        exit(1);
    }
    int pid = fork();
    if(pid==0){
        //子进程
        // 关闭父管道的写入端和子管道的读取端
        close(fd_p2c[WR]); // 显示关闭是为了严谨,不关闭不会报错
        close(fd_c2p[RD]); //
        read(fd_p2c[RD],buf,4);
        printf("child:%d received %s\n", getpid(),buf);
        write(fd_c2p[WR],"pong",4);
    }else if(pid>0){
        close(fd_p2c[RD]);
        close(fd_c2p[WR]);
        // 父进程
        write(fd_p2c[WR],"ping",4);
        int status;
        int child_id = wait(&status);
        printf("child:%d done!\n",child_id);
        read(fd_c2p[RD],buf,4);
        printf("parent:%d received %s\n", getpid(),buf);
        printf("parent:%d done!\n", getpid());
    }
    exit(0);
    return 0;
}

hart 1 starting
hart 2 starting
init: starting sh
$ pingpong
child:4 received ping
child:4 done!
parent:3 received pong
parent:3 done!

注意没有exit(0); 会出现乱码,原因未知,欢迎大神留言解惑:

hart 1 starting
hart 2 starting
init: starting sh
$ pingpong
child:4 received ping
usertrap(): unexpected scause 0x000000000000000d pid=4
            sepc=0x0000000000000100 stval=0x0000000000003f64
child:4 done!
parent:3 received pong
parent:3 done!
usertrap(): unexpected scause 0x000000000000000d pid=3
            sepc=0x0000000000000100 stval=0x0000000000003f64

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

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

您的目标是使用pipe和fork来设置管道。第一个进程将数字2到35输入管道。对于每个素数,您将安排创建一个进程,该进程通过一个管道从其左邻居读取数据,并通过另一个管道向其右邻居写入数据。由于xv6的文件描述符和进程数量有限,因此第一个进程可以在35处停止。

提示:

  • 请仔细关闭进程不需要的文件描述符,否则您的程序将在第一个进程达到35之前就会导致xv6系统资源不足。
  • 一旦第一个进程达到35,它应该使用wait等待整个管道终止,包括所有子孙进程等等。因此,主primes进程应该只在打印完所有输出之后,并且在所有其他primes进程退出之后退出。
  • 提示:当管道的write端关闭时,read返回零。
  • 最简单的方法是直接将32位(4字节)int写入管道,而不是使用格式化的ASCII I/O。
  • 您应该仅在需要时在管线中创建进程。
  • 将程序添加到Makefile中的UPROGS。

如果您的解决方案实现了基于管道的筛选并产生以下输出,则是正确的:

$ make qemu
...
init: starting sh
$ primes
prime 2
prime 3
prime 5
prime 7
prime 11
prime 13
prime 17
prime 19
prime 23
prime 29
prime 31
$

考虑所有小于1000的素数的生成。Eratosthenes的筛选法可以通过执行以下伪代码的进程管线来模拟:

p = get a number from left neighbor
print p
loop:
    n = get a number from left neighbor
    if (p does not divide n)
        send n to right neighbor
p = 从左邻居中获取一个数
print p
loop:
    n = 从左邻居中获取一个数
    if (n不能被p整除)
        将n发送给右邻居

在这里插入图片描述
生成进程可以将数字2、3、4、…、1000输入管道的左端:行中的第一个进程消除2的倍数,第二个进程消除3的倍数,第三个进程消除5的倍数,依此类推。

这是我调试版本的代码,没有在xv6中打印,可以在任何linux中运行。
取数据:lpipe,写数据rpipe, 从图中可以看到,每个矩形的操作是重复的,所以应该用递归调用function primes,
而且每次递归调用,生成新的子进程,继续递归调用。

#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#define RD 0
#define WR 1
/**
 * @brief 寻找素数
 * @param lpipe 左邻居管道
 */
void primes(int lpipe[2]){ //接收的参数当左通道用
    close(lpipe[WR]);
    int first;
    if(read(lpipe[RD],&first,sizeof(int))==sizeof(int)){ // 读到了【左管道】(第一次是main)送过来的数据
        printf("prime %d\n",first);
        printf("get first:%d\n",first);
        // 定义右管道
        int rpipe[2];
        pipe(rpipe); // 生成右管道,做数据过滤
        int data;
        while(read(lpipe[RD], &data, sizeof(int))==sizeof(int)){
            if (data % first){// 除尽的过滤掉,除不尽的留下,放到右管道 
                write(rpipe[WR], &data, sizeof(int));
            }
        }
        if (fork() == 0) {
            primes(rpipe);    // 递归的思想,但这将在一个新的进程中调用
        } else {
            close(rpipe[WR]);// 关闭右管道的写
            wait(0);//等待回收子进程
        }
    }
    
     

    

}
int main(){
    int p[2];
    pipe(p);
    int res;
    for (size_t i = 2; i <= 35; i++)
    {
        // 依次写入初始数据 2,3,4,...35
        res = write(p[WR],&i,sizeof(size_t));
        printf("pid:%d, send:%d, res:%d\n",getpid(),i,res);
    }
    if (fork()==0)
    {   //子进程做筛选素数操作,是递归筛选
        primes(p); 
    }else{
      //父进程啥也不干,等着回收子进程即可
      close(p[WR]); // 这里写关不关闭无所谓,但是谨慎起见,还是关闭为好
      close(p[RD]);//这里必须要关闭读,否则子进程无法从管道读取数据。
      wait(0);  
    }
    exit(0);  
    
}

main函数的 close(p[RD]);//这里必须要关闭读,否则子进程无法从管道读取数据。
读操作只能确保开放给一个进程!这个题目是很难的!

4.find(难度:Moderate)

YOUR JOB

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

在这里插入图片描述

5.xargs(难度:Moderate)

YOUR JOB

编写一个简化版UNIX的xargs程序:它从标准输入中按行读取,并且为每一行执行一个命令,将行作为参数提供给命令。你的解决方案应该在user/xargs.c

下面的例子解释了xargs的行为

$ echo hello too | xargs echo bye
bye hello too
$

注意,这里的命令是echo bye,额外的参数是hello too,这样就组成了命令echo bye hello too,此命令输出bye hello too

请注意,UNIX上的xargs进行了优化,一次可以向该命令提供更多的参数。 我们不需要您进行此优化。 要使UNIX上的xargs表现出本实验所实现的方式,请将-n选项设置为1。例如

$ echo "1\n2" | xargs -n 1 echo line
line 1
line 2
$

提示:

  • 使用fork和exec对每行输入调用命令,在父进程中使用wait等待子进程完成命令。
  • 要读取单个输入行,请一次读取一个字符,直到出现换行符(‘\n’)。
  • kernel/param.h声明MAXARG,如果需要声明argv数组,这可能很有用。
  • 将程序添加到Makefile中的UPROGS。
  • 对文件系统的更改会在qemu的运行过程中保持不变;要获得一个干净的文件系统,请运行make clean,然后make qemu
  • xargs、find和grep结合得很好

ref:https://xv6.dgs.zone/labs/requirements/lab1.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1354614.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端push.js桌面通知库

push.js 官网&#xff1a;https://pushjs.org/ 安装 1,npm 安装方式 npm install push.js --save 2,script引入方式 <script src"https://cdnjs.cloudflare.com/ajax/libs/push.js/0.0.11/push.min.js"></script> 使用 1&#xff0c;获取用户许可…

UnityRenderStreaming使用记录(二)

记录一下发现的问题 1、网页经常出现一直转但是不出现播放按钮的问题 检查发现有几个js文件从外网加载&#xff0c;速度太慢导致的&#xff0c;下载到本地&#xff0c;重新打包webserver.exe就可以了 比如Receiver Sampled的网页在UnityRenderStreaming\WebApp\client\public…

elect函数可以设置等待时间,

欢迎关注博主 Mindtechnist 或加入【智能科技社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;贝叶斯滤波与Kalman估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能&#xff0c…

Mybatis-Plus乐观锁配置使用流程【OptimisticLockerInnerInterceptor】

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家:人工智能学习网站 1.乐观锁实现 1.配置插件 1.XML方式 <bean class"com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerI…

el-table表格动态添加列。多组数据拼接和多层级数据的处理

提示&#xff1a;el-table表格动态添加列 文章目录 前言一、多组数据拼接二、多层级处理三、实际应用中&#xff0c;为避免闪屏&#xff0c;可以表格数据统一渲染总结 前言 需求&#xff1a;富文本编辑器 一、多组数据拼接 <template><div class"test">…

【langchain】入门初探实战笔记(Chain, Retrieve, Memory, Agent)

1. 简介 1.1 大语言模型技术栈 大语言模型技术栈由四个主要部分组成&#xff1a; 数据预处理流程&#xff08;data preprocessing pipeline&#xff09;嵌入端点&#xff08;embeddings endpoint &#xff09;向量存储&#xff08;vector store&#xff09;LLM 终端&#xff…

mac环境下安装部署mysql5.7

下载安装包 进入官网下载MySQL5.7的安装包 https://www.mysql.com/downloads/ 安装包下载完成后双击pkg文件进行安装&#xff0c;无脑点下一步即可&#xff0c;注意安装完成后记得保存最后弹出框的密码 进入系统偏好设置&#xff0c;找到mysql&#xff0c;开启mysql服务…

人工智能教程(四):概率论入门

目录 前言 TensorFlow 入门 SymPy 入门 概率论入门 前言 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。 点击跳转到网站 在本系列的 上一篇文章 中&#xff0c;我们进一步讨论了矩阵和线性代数&#…

macbook录屏快捷键大全,教你快速录制视频

“有人知道macbook电脑有录屏快捷键吗&#xff0c;现在录屏的速度太慢了&#xff0c;每次打开都要浪费不少时间&#xff0c;要是有录屏快捷键&#xff0c;应该会快很多&#xff0c;有哪位大佬知道吗&#xff1f;教教我&#xff01;” 无论是在工作还是生活中&#xff0c;电脑已…

安卓Android Studio读写FM1208CPU卡源码

本示例使用的发卡器&#xff1a;https://item.taobao.com/item.htm?spma1z10.5-c-s.w4002-21818769070.11.6c46789elLwMzv&id615391857885 <?xml version"1.0" encoding"utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout x…

redis复习笔记02(小滴课堂)

分布式缓存Redis6常见核心配置讲解 查看配置文件&#xff1a; 创建配置文件&#xff1a; 配置完我们去验证一下&#xff1a; 启动成功就没有问题了。 可以看到redis日志。 然后我们就可以连接我们的redis了&#xff1a; 设置了密码就需要密码登录了。 如果登录了错误的密码也无…

C/C++汇编学习(二)——学习使用IDA pro

学习使用IDA Pro是一项很有价值的技能&#xff0c;特别是对于那些对逆向工程和软件安全分析感兴趣的人。以下是一些基本步骤和概念&#xff0c;帮助你熟悉IDA Pro的界面和操作。 1. 熟悉IDA Pro界面和基本操作 主界面布局 IDA Pro的主界面包含多个组件&#xff0c;每个组件都…

静态网页设计——个人简介网站

前言 使用经典前端三件套HTMLCSSJavascript编写了一个关于个人简介的静态网页&#xff0c;可以根据自己的需要&#xff0c;十分简单的进行修改。 首页 首页由上方的菜单栏以及菜单栏下面的轮播图组成&#xff0c;再往下走&#xff0c;是关于自己的兴趣爱好的部分&#xff0c…

UG/NX许可证使用效率提升新技术

UG/NX许可证使用效率提升新技术 UG&#xff08;Unigraphics NX&#xff09;是Siemens PLM Software公司出品的一个产品工程解决方案&#xff0c;它为用户的产品设计及加工过程提供了数字化造型和验证手段。近年来随着国家对知识产品保护的不断加强&#xff0c;以前使用盗版软件…

vue3+Ts+Hook的方式实现商城核心功能sku选择器

前言 Hooks是React等函数式编程框架中非常受欢迎的工具&#xff0c;随着VUE3 Composition API 函数式编程风格的推出&#xff0c;现在也受到越来越多VUE3开发者的青睐&#xff0c;它让开发者的代码具有更高的复用度且更加清晰、易于维护。 本文将通过CRMEB商城商品详情sku选择…

Bee的批量插入与事务使用

* Bee 在2.2之前,调用批量插入在每个批都会提交commit,但在2.2改为只调用一次且在事务中,在批量插入的方法内容不再提交,而由事务控制. * * 2.2之前,批量插入使用每一个批次提交一次事务; * 这样,当违反主键约束等就忽略的大批量插入效率是很高的; * 但当事务中有批量插…

Golang Leetcode19 删除链表的倒数第N个节点 递归 双指针法+迭代

删除链表的倒数第N个节点 leetcode19 递归 由于本体是倒数第几个节点&#xff0c;非常适合递归 从终到始 的运行方式 func removeNthFromEnd(head *ListNode, n int) *ListNode {// 创建一个虚拟头节点&#xff0c;简化边界条件处理dummy : &ListNode{Next: head}//检查…

【卫星科普】什么是农业一号卫星和农业二号卫星?

农业一号卫星和农业二号卫星是中国自主研发的两颗重要卫星&#xff0c;主要用于农业领域的监测和研究。 农业一号卫星是中国第一颗具备红边波段传感器的卫星&#xff0c;也是世界上第一颗具备红边波段的宽视场多光谱中高分辨率卫星。这对农业农村遥感监测非常重要&#xff0c;…

阿里云ECS服务器无法访问端口(防火墙在关闭状态也启作用)

问题&#xff1a;一直用得好好的端口&#xff0c;突然在某一时间不可以访问这个端口了 &#xff0c;在服务器录入外网地址访问如下图&#xff1a; 先按正常流程检测&#xff1a; 1 先云服务商的管理网站查看防火墙端口是否开放 看了正常开放了端口&#xff0c;如下图&#xff…

HTML5-简单文件操作

文件操作 简介 概念&#xff1a;可以通过file类型的input控件或者拖放的方式选择文件进行操作 语法格式&#xff1a; <input type"file" multiple>属性 multiple&#xff1a;表示是否选择多个文件 accept&#xff1a;用于设置文件的过滤类型&#xff08;MI…