Sleep功能

通过接受时间参数,调用system_call 指令 sleep实现该功能

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h" int main(int argc,char* argv[])
{
//sleep time
if(argc < 2)
{
printf("error:no time\n");
printf("use: sleep <time>\n");
}
else
{
sleep(atoi(argv[1]));
}
exit(0);
}

本地检测

课程环境为我们提供了本地的检测,需要注意的是要修改python的位置

方法

pingpong

本题的要求是父进程和子进程之间的数据传输

int p[2];
pipe(p);//向p赋值 p[0]=0,p[1]=1

这道题实际上就是pipe和fork的应用。通过创建两个数组分别用于接受父进程到子进程,子进程到父进程的文件描述符。然后通过write和read来控制管道传输

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h" int main(int argc, char* argv[])
{
//pipe
int pf2c[2],pc2f[2];
pipe(pf2c);
pipe(pc2f);
//father progress
if(fork()!=0)
{
//close file-des not use
close(pf2c[0]);
close(pc2f[1]);
//write bit in father2child pipe
write(pf2c[1],"a",1);
char buf;
//read bit from child2father pipe
read(pc2f[0],&buf,1);
//after read printf
printf("%d: received pong\n",getpid());
close(pf2c[1]);
close(pc2f[0]);
wait(0);
}
//child progress
else
{
close(pf2c[1]);
close(pc2f[0]);
char buf;
//read bit from father2child pipe
read(pf2c[0],&buf,1);
printf("%d: received ping\n",getpid());
//writ bit in child2father pipe
write(pc2f[1],&buf,1);
close(pf2c[0]);
close(pc2f[1]);
}
exit(0);
}

Primes

寻找素数

原理就是不断筛选掉素数的倍数,其循环版本大致如下

//true表示不为素数,false表示是素数
bool np[n+1];
np[1] = true;
for(int i = 2;i*i<n+1;i++)
{
for(int j = i*i;j<n+1;j+=i)
{
if(!np[i])
{
np[j] = true;
}
}
}

现在要将这个变为并发程序

将第一重循环的i变为子线程,每个子线程来处理第二重循环。lab中有提示



所以需要使用close关闭一些不会用到的文件描述符,比如父进程操作时,不会用到父进程的写操作和子进程的读操作。子进程操作时不会用到子进程的写操作和父进程的读操作。

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h" //primes
//left pipe -- pleft[2]
__attribute__((noreturn))
void findprimes(int pleft[2])
{
//read the num-list first number
//it's must be the prime
int p;
read(pleft[0],&p,sizeof(p));
//p = -1 --> finish
if(p == -1)
{
exit(0);
}
printf("prime %d\n",p); //next progress find next prime
int pright[2];
pipe(pright); //child progress
if(fork() == 0)
{
//not need use father2child pipe write
close(pright[1]);
//not need use 2father pipe read
close(pleft[0]);
//**func**
findprimes(pright);
}
//father progress -- current -- clear some no-prime
//which k*p
else
{
//close father2child pipe read
close(pright[0]);
int buf;
//clear
while(read(pleft[0],&buf,sizeof(buf)) && buf != -1)
{
if(buf % p != 0)
{
//not k*p write in pright for child progress
write(pright[1],&buf,sizeof(buf));
}
}
buf = -1;
//finish signal
write(pright[1],&buf,sizeof(buf));
//wait child progress finish
wait(0);
exit(0);
}
} int main(int argc,char* argv[])
{
int p[2];
pipe(p); //child progress
if(fork() == 0)
{
//fisrt child progress
//not write for pipe
close(p[1]);
findprimes(p);
exit(0);
}
//father progress
else
{
//not need read for pipe
close(p[0]);
int i;
//write 2->35 in pipe left
for(i = 2;i<36;i++)
{
write(p[1],&i,sizeof(i));
}
//finish sigal
i = -1;
write(p[1],&i,sizeof(i));
}
//wait the first child progress finish then all prime find
wait(0);
exit(0);
}

find

就是对ls的理解

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/fs.h" //copy like ls
//__attribute__((noreturn))
void find(char* path,char* target)
{
char buf[512], *p;
int fd;
struct dirent de;
struct stat st; if((fd = open(path,0))<0)
{
fprintf(2,"find: cannot open %s\n",path);
return ;
}
if(fstat(fd, &st)<0)
{
fprintf(2,"find:cannot stat &s\n",path);
close(fd);
return ;
}
switch(st.type)
{
case T_FILE:
// if fileend like `/target`,get
if(strcmp(path+strlen(path)-strlen(target), target) == 0) {
printf("%s\n", path);
}
break;
case T_DIR:
if(strlen(path) + 1 + DIRSIZ + 1 > sizeof buf){
printf("find: path too long\n");
break;
}
strcpy(buf, path);
p = buf+strlen(buf);
*p++ = '/';
while(read(fd, &de, sizeof(de)) == sizeof(de)){
if(de.inum == 0)
continue;
memmove(p, de.name, DIRSIZ);
p[DIRSIZ] = 0;
if(stat(buf, &st) < 0){
printf("find: cannot stat %s\n", buf);
continue;
}
// not run in '.' or '..'
if(strcmp(buf+strlen(buf)-2, "/.") != 0 && strcmp(buf+strlen(buf)-3, "/..") != 0) {
find(buf, target); // ** func **
}
}
break;
}
close(fd);
} int main(int argc, char *argv[])
{
if(argc < 3){
exit(0);
}
char target[512];
target[0] = '/'; // add '/' begin
strcpy(target+1, argv[2]);
find(argv[1], target);
exit(0);
}

xargs

xargs的功能就是为标准输入的每一行执行一个命令,每一行可以称为该命令的参数,例如



标准输入为1换行2,然后xargs后面的命令是echo line

1和2可以作为参数添加到line后面

得到输出。

参考

有限状态自动机

一系列的状态转换,就是通过对字符串的分析来设置状态。

#include "kernel/types.h"
#include "kernel/stat.h"
#include "user/user.h"
#include "kernel/param.h" #define MAXSZ 512
//define the statemachine
enum state
{
S_WAIT, //wait param input, init state or input is space
S_ARG, //input valid param
S_ARG_END, //valid param end
S_ARG_LINE_END, // valid param enter "1\n"
S_LINE_END, // space enter "1 \n"
S_END, //end
};
//char state
enum char_type
{
C_SPACE,
C_CHAR,
C_LINE_END,
}; //get input string every char type
enum char_type get_char_type(char c)
{
switch(c)
{
case ' ':
return C_SPACE;
break;
case '\n':
return C_LINE_END;
break;
default:
return C_CHAR;
break;
}
}; //change state by the next char
enum state transform_state(enum state cur_state, enum char_type ct)
{
switch(cur_state)
{
case S_WAIT:
if (ct == C_SPACE) return S_WAIT;
if (ct == C_LINE_END) return S_LINE_END;
if (ct == C_CHAR) return S_ARG;
break;
case S_ARG:
if (ct == C_SPACE) return S_ARG_END;
if (ct == C_LINE_END) return S_ARG_LINE_END;
if (ct == C_CHAR) return S_ARG;
break;
case S_ARG_END:
case S_ARG_LINE_END:
case S_LINE_END:
if (ct == C_SPACE) return S_WAIT;
if (ct == C_LINE_END) return S_LINE_END;
if (ct == C_CHAR) return S_ARG;
break;
default:
break;
}
return S_END;
}; //clear params when appear '\n'
void clearArgv(char* x_argv[MAXARG],int beg)
{
for(int i = beg;i<MAXARG;i++)
{
x_argv[i] = 0;
}
} //main
int main(int argc,char* argv[])
{
//if params's length > MAXARG error
if(argc - 1 >= MAXARG)
{
fprintf(2,"xargs: too many arguments\n");
exit(1);
}
char lines[MAXSZ];
char* p = lines;
char* x_argv[MAXARG] = {0}; //the params input save
for(int i = 1;i<argc;i++)
{
x_argv[i-1] = argv[i];
}
//begin index
int arg_beg = 0;
//end index
int arg_end = 0;
//cur index
int arg_cnt = argc-1;
//the begin state
enum state st = S_WAIT; while(st != S_END)
{
if(read(0,p,sizeof(char)) != sizeof(char))
{
st = S_END;
}
else
{
//change state by *p
st = transform_state(st,get_char_type(*p));
}
//if end index bigger than maxsz
if(++arg_end >= MAXSZ)
{
fprintf(2,"xargs: arguments too long\n");
exit(1);
}
switch(st)
{
case S_WAIT: // move arg_beg
++arg_beg;
break;
case S_ARG_END: //end params, save params in x_argv
x_argv[arg_cnt++] = &lines[arg_beg];
arg_beg = arg_end;
*p ='\0';
break;
case S_ARG_LINE_END: // if '\n' save and ouptput
x_argv[arg_cnt++] = &lines[arg_beg];
// no break, same S_LINE_END --> output
case S_LINE_END: // output
arg_beg = arg_end;
*p = '\0';
if (fork() == 0)
{
exec(argv[1], x_argv);
}
arg_cnt = argc - 1;
clearArgv(x_argv, arg_cnt);
wait(0);
break;
default:
break;
}
++p;
}
exit(0);
}

Lab1:Xv6 and Unix utilities的更多相关文章

  1. MIT6.S081/6.828 实验1:Lab Unix Utilities

    Mit6.828/6.S081 fall 2019的Lab1是Unix utilities,主要内容为利用xv6的系统调用实现sleep.pingpong.primes.find和xargs等工具.本 ...

  2. Linux/UNIX 下 “command not found” 原因分析及解决

    在使用 Linux/UNIX 时,会经常遇到 "command not found" 的错误,就如提示的信息,Linux /UNIX 没有找到该命令.原因无外乎你命令拼写错误或 L ...

  3. Kernighan《UNIX 传奇:历史与回忆》杂感

    Brian W. Kernighan 是一个伟大的技术作家,我买了他写的几乎所有书.他近些年的书我买的是 Kindle 电子版,不占地方. 以下是我手上保存的纸版书: Kernighan 的书大多与别 ...

  4. Linux监控工具介绍系列——OSWatcher Black Box

      OSWatcher Balck Box简介 OSWatcher Black Box (oswbb)是Oracle开发.提供的一个小巧,但是实用.强大的系统工具,它可以用来抓取操作系统的性能指标,用 ...

  5. Linux根文件系统分析之init和busybox

    Hi,大家好!我是CrazyCatJack.今天给大家讲解Linux根文件系统的init进程和busybox的配置及编译. 先简单介绍一下,作为一个嵌入式系统,要想在硬件上正常使用的话.它的软件组成大 ...

  6. 【翻译】XV6-DRAFT as of September 3,2014 第0章 操作系统接口

    操作系统接口 操作系统的任务是让多个程序共享计算机(资源),并且提供一系列基于计算机硬件的但更有用的服务.操作系统管理并且把底层的硬件抽象出来,举例来说,一个文字处理软件(例如word)不需要关心计算 ...

  7. 给Android系统安装busybox

    转自:http://blog.csdn.net/lxgwm2008/article/details/38925051 busybox号称Linux平台的瑞士军刀,它集成了100多个最常用的Linux命 ...

  8. OSWatcher Black Box

    Linux监控工具介绍系列--OSWatcher Black Box OSWatcher Balck Box简介 OSWatcher Black Box (oswbb)是Oracle开发.提供的一个小 ...

  9. Web安全工具大汇聚

    http://www.owasp.org/index.PHP/Phoenix/Tools http://sebug.net/paper/other/Web安全工具大汇聚.txt =========== ...

  10. SAE J1850 VPW Implement

    ---恢复内容开始--- OBDII Interface Project When I can ever find enough time away from schoolwork, I try to ...

随机推荐

  1. Vue+ElementUI实现用户管理前后分离实战一:前端篇

    项目介绍 前几天有老铁问我能不能写一个Vue+ElementUI+SpringBoot后端的前后分离项目,最近有点忙,但今天他还是来了!希望对大家能有点帮助,大家还想要点啥也可以加我QQ或给我留言 : ...

  2. centos6关闭防火墙

    service iptable status     --查看防火墙状态 servcie iptables stop     --临时关闭防火墙 chkconfig iptables off      ...

  3. 《深入理解Java虚拟机》(五) JVM调优案例

    目录 问题 排查问题经过了如下的过程: 排除是否数据库卡顿造成 任务管理器 与客户沟通 至此开始通过JVM排查问题: JVM参数介绍 第一次Full GC 第二次Full GC截图 第三次Full G ...

  4. 在MATPool矩池云完成Pytorch训练MNIST数据集

    本文为矩池云入门手册的补充:Pytorch训练MNIST数据集代码运行过程. 案例代码和对应数据集,以及在矩池云上的详细操作可以在矩池云入门手册中查看,本文基于矩池云入门手册,默认用户已经完成了机器租 ...

  5. JS中Date和时间戳转换

    <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="C ...

  6. Linux或者Mac解压乱码问题

    1.unar : 命令行解压工具 2.安装: ubuntu等Linux安装方法:sudo apt install unar mac系统安装方法:brew install unar 现在mac电脑用 T ...

  7. 【Azure 微服务】Service Fabric 部署时遇见了VMExtensionProvisioningError错误: Multiple VM extensions failed to be provisioned on the VM

    问题描述 Deployment  Azure Service Fabric 时,遇见了VMExtensionProvisioningError, 全文如下: Deployment Name: 385A ...

  8. 聊聊图数据库和图数据库的小知识 Vol.02

    2010 年前后,对于社交媒体网络研究的兴起带动了图计算的大规模应用. 2000 年前后热门的是 信息检索 和 分析 ,主要是 Google 的带动,以及 Amazon 的 e-commerce 所用 ...

  9. ChCore—实验 3:进程与线程、异常处理 部分记录

    思考题 1: 内核从完成必要的初始化到用户态程序的过程是怎么样的?尝试描述一下调用关系. 内核启动到用户程序启动的流程: main ├── uart_init ├── mm_init ├── arch ...

  10. 10 个解放双手的 IDEA插件,少些冤枉代码(第三弹)

    大家好,我是小富- 好久没发这种实用贴了,最近用到了一些能提升工作效率的IDEA插件,给小伙伴们分享一下.相信我,我分享的这些插件,都是实实在在能解决实际开发场景中痛处的. 以往的两篇IDEA插件分享 ...