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 ...
随机推荐
- Laravel入坑指南(5)——请求与响应
作为互联网典型的Web应用,接收用户请求的数据,并将处理的结果向用户进行响应,是最基础也是最必备的功能.在原生的PHP中,我们常用$_POST.$_GET.$_REQUEST和$_FILES对不同的请 ...
- org.apache.http.client.ClientProtocolException: URI does not specify a valid host name:localhost:xxx
今天部署应用的时候遇到的,总结一下我知道的有2个原因: 1.地址前要加http:// 这就是标题报错的原因,他用的是localhost:xxx 2.地址本身拼错了也会报这个,例如地址:http:// ...
- win32 - 将控制台输出重定向到txt文本上
这里需要两个app. parent.cpp #include <Windows.h> #include <stdio.h> int main() { SECURITY_ATTR ...
- 硬件开发笔记(十二):RK3568底板电路电源模块和RTC模块原理图分析
前言 做硬件做系统做驱动,很难从核心板做起,所以我们先依赖核心板,分析底板周围的电路,然后使用AD绘制原理图和设计PCB,打样我司测试底板,完成硬件测试,再继续系统适配,驱动移植,从而一步一步完善 ...
- Hi3516开发笔记(十一):通过HiTools使用网口将uboot、kernel、roofts烧写进eMMC
前言 前面烧写一直时烧写进入flush,是按照分区烧写.定制的板子挂的是eMMC,前面的烧写步骤一致,但是在烧写目标则时烧写eMMC了. 重新走一遍从无到有通过网口刷定制板卡的uboot.ker ...
- 【LeetCode字符串#02】替换空格+IP地址无效化,reserve和resize的区别分析
替换空格 力扣题目链接(opens new window) 请实现一个函数,把字符串 s 中的每个空格替换成"%20". 示例 1: 输入:s = "We are hap ...
- SpringBoot Starter大全
spring Boot应用启动器基本的一共有44种,具体如下 1)spring-boot-starter 这是Spring Boot的核心启动器,包含了自动配置.日志和YAML. 2)spring-b ...
- 【Azure 应用服务】Azure Function Python函数部署到Azure后遇见 Value cannot be null. (Parameter 'receiverConnectionString') 错误
问题描述 使用VS Code创建Python Function,处理Event Hub中的数据.当部署到Azure Function App后,函数无法执行,查看 Function 日志出现 Valu ...
- python执行JavaScript代码出现编码问题的解决方案
当我们安装好nodejs环境,想在python代码中去调用JavaScript代码,常常会出现编码的问题. 举个例子: python代码如下: 点击查看代码 import execjs f = ope ...
- Jmeter参数化-用户自定义变量
一 首先我们先来了解下jmeter 做参数化的目的: 1通过参数化来集中管理配置和测试数据 2通过参数化实现数据驱动测试 二 线程组添加配置元件中的用户自定义变量 添加变量名称,变量值 三 使用变量 ...