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. SpringBoot整合ip2region实现使用ip监控用户访问地域来源

    举个栗子 最*,多*台都上线了展示*期发帖所在地功能,比如抖音.微博.百度,像下面那样: 那么这个功能都是如何实现的呢? 一般有两个方法:GPS 定位的信息和用户 IP 地址. 由于每个手机都不一定会 ...

  2. k8s(Kubernetes) 常用命令配置

    一.基础命令 $ kubectl create -f ./my-manifest.yaml # 创建资源 $ kubectl create -f ./my1.yaml -f ./my2.yaml # ...

  3. udp循环发消息,sockerserver,文件校验,服务器合法性校验---day29

    1.udp循环发消息 # ### 客户端 import socket sk = socket.socket(type=socket.SOCK_DGRAM) while True: #发送消息 mess ...

  4. 国内如何快速访问GitHub

    1.国内如何快速访问gibhub -FQ的方法无非就是用软件,这种就不介绍了 -本次介绍的是修改本地系统主机hosts文件,绕过国内dns解析,达到快速访问github 打开https://tool. ...

  5. 用BootstrapBlazor制作修改订单字段的页面

    1.在Shared文件夹下新增一个razor 2.页面初始化的时候获取订单信息 准备一个名为OrderId的参数 准备重写页面初始化时的方法 改成异步的形式来重写 4.获取数据 就3行代码. 声明这个 ...

  6. Redis动态配制,限内存,免重启

    p.p1 { margin: 0; font: 14px Menlo; color: rgba(0, 255, 255, 1); background-color: rgba(0, 0, 0, 0.8 ...

  7. 【Azure Redis】PHPRedis遇见SSL Connection Timeout问题

    问题描述 PHP Redis客户端遇见使用SSL Connection timeout,遇见问题后,切换回去Non-SSL没有出现问题.但是切换回SSL后,还是偶尔遇见Connection timeo ...

  8. 【Azure APIM】解决APIM Self-hosted Gateway在AKS上,最开始访问时候遇见的404问题

    问题描述 根据APIM官方文档,创建Self-hosted 网关在AKS中( 使用 YAML 将自承载网关部署到 Kubernetes :https://docs.azure.cn/zh-cn/api ...

  9. Nebula Importer 数据导入实践

    本文首发于 Nebula Graph Community 公众号 前言 Nebula 目前作为较为成熟的产品,已经有着很丰富的生态.数据导入的维度而言就已经提供了多种选择.有大而全的Nebula Ex ...

  10. Kotlin扩展函数与属性原理解析

    一.扩展函数 扩展函数可以方便地给现有类增加属性和方法而不改动类地代码. 二.原理 fun String.addTo(s: String): String{ return this + s } 反编译 ...