Lab1:Xv6 and Unix utilities
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的更多相关文章
- MIT6.S081/6.828 实验1:Lab Unix Utilities
Mit6.828/6.S081 fall 2019的Lab1是Unix utilities,主要内容为利用xv6的系统调用实现sleep.pingpong.primes.find和xargs等工具.本 ...
- Linux/UNIX 下 “command not found” 原因分析及解决
在使用 Linux/UNIX 时,会经常遇到 "command not found" 的错误,就如提示的信息,Linux /UNIX 没有找到该命令.原因无外乎你命令拼写错误或 L ...
- Kernighan《UNIX 传奇:历史与回忆》杂感
Brian W. Kernighan 是一个伟大的技术作家,我买了他写的几乎所有书.他近些年的书我买的是 Kindle 电子版,不占地方. 以下是我手上保存的纸版书: Kernighan 的书大多与别 ...
- Linux监控工具介绍系列——OSWatcher Black Box
OSWatcher Balck Box简介 OSWatcher Black Box (oswbb)是Oracle开发.提供的一个小巧,但是实用.强大的系统工具,它可以用来抓取操作系统的性能指标,用 ...
- Linux根文件系统分析之init和busybox
Hi,大家好!我是CrazyCatJack.今天给大家讲解Linux根文件系统的init进程和busybox的配置及编译. 先简单介绍一下,作为一个嵌入式系统,要想在硬件上正常使用的话.它的软件组成大 ...
- 【翻译】XV6-DRAFT as of September 3,2014 第0章 操作系统接口
操作系统接口 操作系统的任务是让多个程序共享计算机(资源),并且提供一系列基于计算机硬件的但更有用的服务.操作系统管理并且把底层的硬件抽象出来,举例来说,一个文字处理软件(例如word)不需要关心计算 ...
- 给Android系统安装busybox
转自:http://blog.csdn.net/lxgwm2008/article/details/38925051 busybox号称Linux平台的瑞士军刀,它集成了100多个最常用的Linux命 ...
- OSWatcher Black Box
Linux监控工具介绍系列--OSWatcher Black Box OSWatcher Balck Box简介 OSWatcher Black Box (oswbb)是Oracle开发.提供的一个小 ...
- Web安全工具大汇聚
http://www.owasp.org/index.PHP/Phoenix/Tools http://sebug.net/paper/other/Web安全工具大汇聚.txt =========== ...
- SAE J1850 VPW Implement
---恢复内容开始--- OBDII Interface Project When I can ever find enough time away from schoolwork, I try to ...
随机推荐
- Js中数组空位问题
Js中数组空位问题 JavaScript中数组空位指的是数组中的empty,其表示的是在该位置没有任何值,而且empty是区别于undefined的,同样empty也不属于Js的任何数据类型,并且在J ...
- scrcpy-Android投屏神器
介绍 scrcpy 是免费开源的投屏软件,支持将安卓手机屏幕投放在 Windows.macOS.GNU/Linux 上,并可直接借助鼠标在投屏窗口中进行交互和录制. 下载scrcpy 解压. http ...
- Java Enumeration接口详解
二话不说,来看官方文档: public interface Enumeration<E> An object that implements the Enumeration interfa ...
- Java集合框架学习(八) HashMap详解
HashMap介绍 HashMap是一个基于Map的集合类,用于存储Key和Value的键值对. 通常用HashMap<Key, Value> or HashMap<K, V> ...
- docker启动nginx https自签名证书配置
启动测试应用时, 有时需要自己配置证书签名: 1 使用系统自带openssl openssl req \ > -x509 \ > -nodes \ > -days 365 \ > ...
- 深入理解Go语言(04):scheduler调度器-GMP里结构体源码分析
在前面一节中简单介绍了golang的调度模型-GPM模型,介绍了他们各自的作用.这篇文章就来看看他们的源码结构. Go版本:go1.13.9 M结构体 M结构体是OS线程的一个抽象,主要负责结合P运行 ...
- Windows系统下的输入法选择
总共用过5款输入法:搜狗拼音输入法,QQ拼音输入法,谷歌拼音输入法,手心输入法,小狼毫. 搜狗输入法功能最强大,词库也很全,基本上对于盲打的输入纠错很准确,但是因为后台会启动多个服务,会占很多内存资源 ...
- mysql日期范围查找(两个日期之间的记录)
转自:https://blog.csdn.net/lzxlfly/article/details/97577575?utm_medium=distribute.pc_relevant_t0.none- ...
- h5页面在微信打开,ios底部存在返回横条的问题
我的问题比较简单,一个处理链接的页面,二次跳转进入真正的页面,导致ios出现返回横条,点击后退回到了处理链接页面.因为这个后退不会重新加载,导致一直处在处理链接的这个空页面. 所以我用replace代 ...
- Linux驱动开发笔记(四):设备驱动介绍、熟悉杂项设备驱动和ubuntu开发杂项设备Demo
前言 驱动的开发需要先熟悉基本概念类型,本篇讲解linux杂项设备基础,还是基于虚拟机ubuntu去制作驱动,只需要虚拟机就可以尝试编写注册杂项设备的基本流程. linux三大设备驱动 字符设 ...