MIT 6.S081---Lab util: Unix utilities

环境搭建

基本环境

选择的是Vmware+ubuntu的配置,注意ubuntu的版本一定要是20.04,作者试过16版本,不行,建议直接安装20.04版,不然环境配置都浪费不少时间有点得不偿失。(Vmware可以用Virtualbox代替)

qemu+xv6

参考官网教程
ps:刚装好的系统可以先更换镜像源(参考ubuntu 20.04 LTS 更换阿里云源)
这里将官网教程流程拷贝下来供大家拷贝:
第一步:


sudo apt-get install git build-essential gdb-multiarch qemu-system-misc gcc-riscv64-linux-gnu binutils-riscv64-linux-gnu 

第二步:

sudo apt-get remove qemu-system-misc
sudo apt-get install qemu-system-misc=1:4.2-3ubuntu6

测试结果如下显示就是对的:

# in the xv6 directory
make qemu
# ... lots of output ...
init: starting sh
$

gitee配置

本处采用git来协调不同平台的代码,由于gitub比较慢于是将代码上传到gitee上(上传的时候可能会显示冲突,解决方法参考:代码冲突强制覆盖上传),至于gitee如何配置环境可以参考Windows环境安装及配置git并连接gitee远程仓库和ubuntu下Git的安装和使用(针对gitee)

实验部分

sleep (easy)

实现一个简单的休眠函数,容易,调api即可

//sleep.c
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"int main(int argc, char *argv[]) {// int i;if (argc == 2) {sleep(atoi(argv[1]));} else {fprintf(2, "there is a need for an augument to determin the time to sleep");exit(1);}exit(0);
}

pingpong (easy)

考察到了pipe()函数的使用,使用管道一端写一端读即可。

//pingpong.c
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"char buf[96];char tmp[100];char* itoch(int input) {int i = 0;int l, r;while (input != 0) {tmp[i++] = (input % 10) + '0';input /= 10;}l = 0;r = i - 1;while (l < r) {char temp = tmp[l];tmp[l] = tmp[r];tmp[r] = temp;l++;r--;}tmp[i] = '\0';// fprintf(1, tmp);return tmp;
}int main(int argc, char *argv[]) {int pftos[2], pstof[2];pipe(pftos);pipe(pstof);// int pid = fork();// read// getpidif (fork() == 0) {//son pidclose(pftos[1]);close(pstof[0]);// fprintf(1, "son read\n");if (read(pftos[0], buf, sizeof(buf)) != 1) {fprintf(2, "ping read error");exit(1);}// fprintf(1, "son read success\n");char* tmp = itoch(getpid());fprintf(1, tmp);fprintf(1, ": ");fprintf(1, "received ping\n");if (write(pstof[1], "i", 1) != 1) {fprintf(2, "pong write error");exit(1);}close(pftos[0]);close(pstof[1]);exit(0);}//parent pidclose(pftos[0]);close(pstof[1]);// fprintf(1, "father write begin\n");if (write(pftos[1], "o", 1) != 1) {fprintf(2, "ping write error");exit(1);}// fprintf(1, "father write success\n");if (read(pstof[0], buf, sizeof(buf)) != 1) {fprintf(2, "pong read error");exit(1);}char* tmp = itoch(getpid());fprintf(1, tmp);fprintf(1, ": ");fprintf(1, "received pong\n");wait(0);close(pftos[1]);close(pstof[0]);exit(0);
}

primes (moderate)/(hard)

通过筛子来筛选,具体如下图所示:
在这里插入图片描述
需要注意两点:

  1. 注意文件描述符的关闭,如果不及时关闭描述符可能会用尽文件描述符;
  2. 注意关闭管道的写端,当管道的写端的引用为0时read读端才会返回零,代表文件结束。
    本处的代码并没有优化到最好,个人认为更好的实现可参考:6.S081-Lab1 总结笔记(0基础向)
#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/spinlock.h"typedef enum {true = 1,false = 0
} bool;void buildProcess(int listenfd, int writefd) {int num;int self = -1;int status = fork();if (status == 0) {bool next = false;close(writefd);close(0);dup(listenfd);close(listenfd);//close(1);//dup(pfd[1]);//close(pfd[1]);int pfd[2];pipe(pfd);while (1) {int read_bytes = read(0, &num, 4);if (read_bytes == 0 || read_bytes == -1) {break;}if (self == -1) {self = num;printf("prime %d\n", num);continue;}if (num % self != 0) {if (!next) {next = true;buildProcess(pfd[0], pfd[1]);}write(pfd[1], &num, 4); }} close(pfd[0]);close(pfd[1]);close(0);wait(0);exit(0);} else if (status == -1) {fprintf(2, "fork error");exit(1);} }int main(int argc, char* argv[]) {int i;bool next = false;int pfd[2];pipe(pfd);for (i = 2; i <= 35; ++i) {if (i == 2) {printf("prime %d\n", i);}if (i % 2 == 1) {if (!next) {next = true;buildProcess(pfd[0], pfd[1]);close(pfd[0]);}write(pfd[1], &i, 4);} }close(pfd[1]);printf("end");wait(0);exit(0);
}

注释:有个待解决的问题,就是pipe后的两个文件描述符中,似乎不能将写端重定向到文件描述符1,具体原因待阅读源码后确认。

find (moderate)

这题算比较简单了,注意参考usr/find.c

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/fs.h"void find(const char* root, const char* target) {char buf[512], *p;int fd;struct dirent de;struct stat st;if((fd = open(root, 0)) < 0){fprintf(2, "find: cannot open %s\n", root);return;}if(fstat(fd, &st) < 0){fprintf(2, "find: cannot stat %s\n", root);close(fd);return;}if (st.type == T_FILE) {fprintf(2, "%s is no a directory!!!\n", root);close(fd);return;}if(strlen(root) + 1 + DIRSIZ + 1 > sizeof buf){printf("ls: path too long\n");}strcpy(buf, root);p = buf+strlen(buf);*p++ = '/';while(read(fd, &de, sizeof(de)) == sizeof(de)){if(de.inum == 0 || strcmp(de.name, ".") == 0 || strcmp(de.name, "..") == 0) continue;strcpy(p, de.name);int tmpfd;if((tmpfd = open(buf, 0)) < 0){fprintf(2, "open: cannot open %s\n", buf);return;}if(fstat(tmpfd, &st) < 0){fprintf(2, "fstat: cannot stat %s\n", buf);close(tmpfd);return;}if (st.type == T_FILE) {if (strcmp(de.name, target) == 0) {printf("%s/", root);printf("%s\n", de.name);}} else if (st.type == T_DIR) {find(buf, target);}close(tmpfd);}close(fd);
}int main(int argc, char* argv[]) {if (argc != 3) {fprintf(2, "too many or too few parameters\n");exit(1);}find(argv[1], argv[2]);exit(0);
}

xargs (moderate)

注意exec的参数,别的话就是些细节啦

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"char buf[1024];int main(int argc, char* argv[]) {int i;int line = 0;int size = read(0, buf, sizeof buf);char* input[argc];for (i = 1; i < argc; ++i) {input[i - 1] = argv[i];}if (size == -1) {fprintf(2, "read error");}for (i = 0; i < size; i++) {if (buf[i] == '\n') {line++;}}char arguments[line][32];int pos = 0, curr = 0;for (i = 0; i < size; ++i) {if (buf[i] == '\n') {arguments[curr][pos] = '\0';curr++;pos = 0;} else {arguments[curr][pos++] = buf[i];}}for (i = 0; i < line; ++i) {input[argc - 1] = arguments[i];if (fork() == 0) {exec(argv[1], input);exit(0);}wait(0);}exit(0);
}

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

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

相关文章

【消息中间件】Rabbitmq消息可靠性、持久化机制、各种消费

原文作者&#xff1a;我辈李想 版权声明&#xff1a;文章原创&#xff0c;转载时请务必加上原文超链接、作者信息和本声明。 文章目录 前言一、常见用法1.消息可靠性2.持久化机制3.消息积压批量消费&#xff1a;增加 prefetch 的数量,提高单次连接的消息数并发消费&#xff1a;…

门诊病历系统教程,社区诊所电子处方系统软件操作教程

一、软件程序问答 门诊病历系统教程&#xff0c;社区诊所电子处方系统软件操作教程 1、电子处方软件在开处方时候&#xff0c;可以一键导入模板吗&#xff1f; 如下图&#xff0c;软件以 佳易王诊所电子处方软件V17.1为例说明 软件右侧点击 配方模板&#xff0c;只需输入症…

从零开始学Python系列课程第17课:容器型数据类型之列表(上)

前言 列表算是 Python 中比较常用的一种容器型数据类型&#xff0c;那么什么是列表&#xff0c;列表有什么样的作用致使它在 Python 中这么受欢迎呢&#xff1f;这便是接下来我们要一起讨论的问题。 在不久之前我们讲过变量&#xff0c;我们将数据使用变量保存&#xff0c;但是…

08.哲说建造者模式(Builder Pattern)

“The odds that we’re in ‘base reality’ is one in billions.” —— Elon Musk 这段话出自马斯克在2016年的一次演讲&#xff0c;“人类活在真实世界的几率&#xff0c;可能不到十亿分之一”。此言一出&#xff0c;可谓一石激起千层浪。有人嘲讽马斯克是“语不惊人死不休…

[2024] 十大免费电脑数据恢复软件——轻松恢复电脑上已删除文件

哈喽大家好&#xff01;你有没有需要适用于电脑的免费数据恢复软件呢&#xff1f;数据丢失可是个烦心事&#xff0c;无论是硬件故障还是软件损坏&#xff0c;甚至是意外删除、格式化或计算机病毒&#xff0c;都让人郁闷至极。当你遇到数据丢失的情况时&#xff0c;你一定希望能…

【Git】Git的基本操作

前言 Git是当前最主流的版本管理器&#xff0c;它可以控制电脑上的所有格式的文件。 它对于开发人员&#xff0c;可以管理项目中的源代码文档。&#xff08;可以记录不同提交的修改细节&#xff0c;并且任意跳转版本&#xff09; 本篇博客基于最近对Git的学习&#xff0c;简单介…

Python中的用户交互函数详解,提升用户体验!

更多Python学习内容&#xff1a;ipengtao.com 用户进行交互的Python应用程序&#xff0c;有许多常用的用户交互函数可以帮助创建更具吸引力和友好的用户界面。本文将介绍一些常用的Python用户交互函数&#xff0c;并提供详细的示例代码&#xff0c;以帮助大家更好地理解它们的用…

右键添加 idea 打开功能

1.开始运行regedit 2.找到: HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Directory\shell _3.开始设置 一、右键shell目录新建项Idea二、右键Idea新建command三、选择Idea 右侧空白出新建字符串 名字为Icon 值填入idea的运行程序地址 四、选择command 默认项填入idea的运行程序地址…

技术探秘:在RISC Zero中验证FHE——RISC Zero应用的DevOps(2)

1. 引言 前序博客&#xff1a; 技术探秘&#xff1a;在RISC Zero中验证FHE——由隐藏到证明&#xff1a;FHE验证的ZK路径&#xff08;1&#xff09; 技术探秘&#xff1a;在RISC Zero中验证FHE——由隐藏到证明&#xff1a;FHE验证的ZK路径&#xff08;1&#xff09; 中&…

【privateGPT】使用privateGPT训练您自己的LLM

了解如何在不向提供商公开您的私人数据的情况下训练您自己的语言模型 使用OpenAI的ChatGPT等公共人工智能服务的主要担忧之一是将您的私人数据暴露给提供商的风险。对于商业用途&#xff0c;这仍然是考虑采用人工智能技术的公司最大的担忧。 很多时候&#xff0c;你想创建自己…

【GOLANG】使用插件 Goanno 的方式来对方法、接口、结构体注释模板配置

直接 使用插件 Goanno 的方式来对方法、接口、结构体注释模板配置 1、简单安装 Goanno 插件 File->Settings->Plugins , 搜索 Goanno Normal Method 配置内容如下&#xff1a; // Title ${function_name} // Description ${todo} // Author mumu ${date} ${time} // Par…

技能分析:这就是人们写在简历上的内容

您希望您的技能部分听起来像其他人一样吗&#xff1f;另一方面&#xff0c;您是否想遗漏一项顶级技能&#xff0c;因为许多其他简历也列出了它&#xff1f;在脱颖而出和涵盖雇主寻求的所有技能之间找到平衡可能是一个挑战。 优秀的简历技能部分会考虑到每个雇主所寻求的特质。…

海云安亮相2023北京国际金融安全论坛,助力金融企业数字化转型降本增效

近日&#xff0c;2023北京国际金融安全论坛暨金融科技标准认证生态大会在北京金融安全产业园成功举办。深圳海云安网络安全技术有限公司&#xff08;以下简称“海云安”&#xff09;受邀参展亮相此次大会。海云安作为国内领先的金融科技服务商&#xff0c;展示了开发安全系列产…

Unity坦克大战开发全流程——开始场景——排行榜数据逻辑

开始场景——排行榜数据逻辑 排行榜单条数据 排行榜列表 然后在数据管理类中声明一个对应的字段 初始化数据 然后再在上一节课所编写的UpdatePanelInfo函数中处理数据更新的逻辑 时间换算算法 然后再在数据管理类中编写一个在排行榜中添加数据的方法以提供给外部 直到当前RankI…

【BERT】深入理解BERT模型1——模型整体架构介绍

前言 BERT出自论文&#xff1a;《BERT&#xff1a;Pre-training of Deep Bidirectional Transformers for Language Understanding》 2019年 近年来&#xff0c;在自然语言处理领域&#xff0c;BERT模型受到了极为广泛的关注&#xff0c;很多模型中都用到了BERT-base或者是BE…

搜索算法和推荐算法、广告算法的区别

广告和推荐算法的技术框架比较相似&#xff0c;在线计算时都分为召回&#xff08;candidates generating&#xff09;和排序&#xff08;candidates ranking&#xff09;两个阶段&#xff08;这似乎是计算资源有限条件下&#xff0c;所有检索问题的通用架构&#xff09;。 在某…

RabbitMQ详解

RabbitMQ 概念 RabbitMQ 是一个由 Erlang 语言开发的 AMQP 的开源实现。 AMQP &#xff1a;Advanced Message Queue&#xff0c;高级消息队列协议。它是应用层协议的一个开放标准&#xff0c;为面向消息的中间件设计&#xff0c;基于此协议的客户端与消息中间件可传递消息&a…

2023年全国网络安全行业职业技能大赛数据安全管理员操作技能赛题(样题)

2023年全国网络安全行业职业技能大赛数据安全管理员操作技能赛题(样题) 2023年全国网络安全行业职业技能大赛数据安全管理员操作技能赛题(样题) 第一部分&#xff1a;数据安全防护(30%) 第二部分&#xff1a;数据安全管理(30%) 第三部分&#xff1a;数据安全处置(40%) 项目介绍…

【JavaEE】多线程(7) -- 线程池的概念和简单实现

目录 1.线程池是什么 2.标准库中的线程池 2.1ThreadPoolExecutor 2.2构造方法参数介绍 2.3拒绝策略(面试易考) 2.4Executor的使用 3.实现线程池 1.线程池是什么 线程池是一种用来管理线程的机制&#xff0c;它可以有效地控制线程的创建、复用和销毁&#xff0c;从而提高程…

程序的编译、链接

目录 前言&#xff1a; 前置知识回顾 宏 宏定义常量 宏定义语句 宏定义函数 条件编译 应用场景 编译过程概览 预编译阶段 编译阶段 汇编阶段 链接阶段 前言&#xff1a; 在ANSI C的任何一种实现中&#xff0c;存在两种不同的环境&#xff0c;第1种是翻译环境&#x…