首页 > 其他分享 >Lab1:Xv6 and Unix utilities

Lab1:Xv6 and Unix utilities

时间:2024-03-02 15:55:05浏览次数:25  
标签:pipe END int Lab1 utilities char Unix include buf

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中有提示
image
所以需要使用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的功能就是为标准输入的每一行执行一个命令,每一行可以称为该命令的参数,例如
image
标准输入为1换行2,然后xargs后面的命令是echo line
1和2可以作为参数添加到line后面
得到输出。
参考

有限状态自动机

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

#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

相关文章

  • 自定义 DataLoader 时应使用 Unix 系统
    自定义Dataset类PyTorch允许自定义Dataset类,并由此获得DataLoader,能方便训练时获得batch:fromtorch.utils.dataimportDataLoader,Datasetimporth5pyimportosclassRadarDataset(Dataset):def__init__(self,directory):...def__len__(s......
  • lunix vscode笔记
    笨死了笨死了笨死了笨死了笨死了笨死了笨死了笨死了笨死了笨死了笨死了笨死笨死了笨死了笨死了笨死了笨死了笨死了笨死了笨死了笨死了笨死了笨死了笨死了死了笨死了笨死了笨死了笨死了笨死了笨死了笨死了笨死了笨死了笨死了笨死了笨死了笨死了笨死了笨死了笨死了笨死了笨死了笨死......
  • 《Unix高级编程》src
    《Unix高级编程》src.3e.tar.gz编译运行-Ubuntu环境:WSL2--Ubuntu下载文件1.从官网上下载apue.3e源码:命令:wgethttp://www.apuebook.com/src.3e.tar.gz解压文件命令:tar-zxvfsrc.3e.tar.gz这里也可以在win环境下解压好托到Ubuntu虚拟机里源码编译接下来我们可以......
  • psql: 无法联接到服务器: 没有那个文件或目录 服务器是否在本地运行并且在 Unix 域套
    今天在服务器上用root用户输入pgsql和pg_dump报错如下 首先检查了下pg的状态发现正常systemctlstatuspostgresql 然后尝试输入pg_dump-h127.0.0.1psql-h127.0.0.1不再报错 添加了-h127.0.0.1原因未知,待解决...... 第二次尝试添加了环境变量vim /et......
  • Tenable Nessus 10.7.0 (Unix, Linux, Windows) - #1 漏洞评估解决方案
    TenableNessus10.7.0(Unix,Linux,Windows)-#1漏洞评估解决方案发布Nessus试用版自动化安装程序,支持macOSSonoma、RHEL9和Ubuntu22.04请访问原文链接:TenableNessus10.7.0(Unix,Linux,Windows)-#1漏洞评估解决方案,查看最新版。原创作品,转载请保留出处。......
  • 【XV6】 Xv6 and Unix utilities
    代码:https://github.com/JasenChao/xv6-labs.git运行xv6实验环境使用的是Ubuntu20.04,需要安装一些工具:sudoapt-getinstallgitbuild-essentialgdb-multiarchqemu-system-miscgcc-riscv64-linux-gnubinutils-riscv64-linux-gnu安装完成后验证qemu是否安装成功,成功的话......
  • MySQL表结构及数据对比工具:MySQL Utilities
    简介MySQLUtilities是一组基于python语言编写的python库的命令行实用工具集,依赖于python2.6。该工具提供了MySQL数据库运维工程中常用的一些工具,诸如克隆、复制、比较、差异、导出、导入、安装、配置、索引、磁盘查看等等。Linux下安装yuminstallmysql-utilities.noarch......
  • [转帖]Unix操作系统的前世今生
    Unix是一种多用户、多任务操作系统,最初由AT&T贝尔实验室的肯·汤普逊(KenThompson)和丹尼斯·里奇(DennisRitchie)等人开发于上世纪70年代初。它被设计成一种通用的操作系统,支持跨多种硬件平台,并提供了许多先进的特性,如多任务处理、分时处理、多用户能力和可移植性。Unix的......
  • 《UNIX网络编程 卷2:进程间通信(第2版)》PDF
    内容简介《UNIX网络编程.卷2:进程间通信(第2版)》是一部UNIX网络编程的经典之作!进程间通信(IPC)几乎是所有Unix程序性能的关键,理解IPC也是理解如何开发不同主机间网络应用程序的必要条件。《UNIX网络编程.卷2:进程间通信(第2版)》从对PosixIPC和SystemVIPC的内部结构开始讨论,全面......
  • Caused by: java.lang.IllegalStateException: A unix domain socket connection requ
    Causedby:java.lang.IllegalStateException:Aunixdomainsocketconnectionrequiresepollorkqueueandneitherisavailable出现这个错误,首先确保自己的操作系统是否支持epoll,或者kqueue。如果支持。请导入netty的大库,lettuce中好像缺失了一部分,我怀疑是这是怀疑,......