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);
}
标签:pipe,END,int,Lab1,utilities,char,Unix,include,buf
From: https://www.cnblogs.com/XTG111/p/18041799