您好,欢迎来到筏尚旅游网。
搜索
您的当前位置:首页操作系统实践报告

操作系统实践报告

来源:筏尚旅游网
操作系统实践报告

操作系统实践报告 多进程题目

: 实现shell程序,要求具备如下功能 支持命令参数

$ echo arg1 arg2 arg3 $ ls /bin /usr/bin /home 实现内置命令cd、pwd、exit $ cd /bin $ pwd /bin 思路:

说明:首先设置一个死循环模仿shell终端,读取用户的输入,并且根据空格将输入拆分成字符串数组,然后调用excute这个子函数进行处理。

1.echo

根据数组第一个元素来判断命令是什么,判断出是ehco后,fork一个新的进程,将其后的内容

一个个输出出来,并且父进程等待子进程退出后再执行,确保输出在屏幕上时不被打断。

2.ls

3.读取用户输入并且根据拆分的数组判断出是ls命令后,fork一个新的进程,调用execlp函数将

/bin/ls下的ls程序装入子进程并将拆分的数组参数部分传递给ls即可,同样的,父进程等待子进程退出,确保输出在屏幕上不被打断。

4.cd

5.同样是根据输入并拆分成数组后判断出是cd命令后,fork一个新的进程,然后调用chdir并将拆

分数组的参数部分传递给chdir作为实参即可。

6.pwd

同样是根据输入并拆分成数组后判断出是pwd命令后,fork一个新的进程,然后调用

system(\"pwd\")即可,此命令也可以用来验证上面的cd命令是否正确执行。

7.exit

8.根据用户输入逼格拆分的数组判断出是exit命令后,excute子函数返回-1,在循环中检测excute

的返回值,如果是-1则直接return,退出模仿的shell终端。 : 实现shell程序,要求在第1版的基础上,添加如下功能 实现文件重定向 $ echo hello >log $ cat log Hello 思路:

接的描述,若判断出是echo命令后,要再次判断拆分的字符串数组中有无“>”出现,如果

有,则把“>”之前、echo之后的内容作为输出,把“>”之后到“>”之后的第一个空白字符作为文件名,fopen创建文件并fwrite将输出内容输出到该文件中,并关闭文件。

和的源代码: #include <> #include <> #include <> #include <> #include #include #include <> #define LEN 256 #define WIDTH 256

#define HEIGHT 10

void split(char source[],char dest[HEIGHT][WIDTH]) { char *p;

p=strsep(&source,\" \"); int i=0;

for(i=0;p[i]!='\\0';i++){ dest[0][i]=p[i]; }

dest[0][i]='\\0'; int j=1; while(p){

p=strsep(&source,\" \"); if(p){

for(i=0;p[i]!='\\0';i++){ dest[j][i]=p[i]; }

dest[j][i]='\\0'; j++; } } }

int execute(char comm[HEIGHT][WIDTH]) {

if(strcmp(comm[0],\"echo\")==0){ int pid=fork(); if(pid==0){ int i=0; int is=0;

for(i=1;comm[i][0]!='\\0';i++){

if(comm[i][0]=='>'){ is=1; break; } }

if(is==1){ puts(comm[i+1]);

FILE *fp=fopen(comm[i+1],\"w+\"); int j=0;

for(j=1;j fseek(fp,0,SEEK_END);

fwrite(comm[j],strlen(comm[j]),1,fp); }

fclose(fp); }else{ int j=0;

for(j=1;comm[j][0]!='\\0';j++){ printf(\"%s\printf(\" \"); }

printf(\"\\n\"); } }else{ int status; wait(&status); }

}else if(strcmp(comm[0],\"ls\")==0){ int pid=fork(); if(pid==0){

if(comm[1][0]=='\\0'){

execlp(\"/bin/ls\}else{

execlp(\"/bin/ls\} }else{ int status; wait(&status); }

}else if(strcmp(comm[0],\"cd\")==0){ int pid=fork(); if(pid==0){ chdir(comm[1]); }else{ int status; wait(&status); }

}else if(strcmp(comm[0],\"pwd\")==0){ int pid=fork(); if(pid==0){ system(\"pwd\"); }else{ int status; wait(&status); }

}else if(strcmp(comm[0],\"exit\")==0){ return -1; } return 1; }

int main()

{ while(1){

char command[LEN];

char splitArray[HEIGHT][WIDTH]={{'\\0'}}; printf(\"%s\gets(command);

split(command,splitArray); int i=0;

if(-1==execute(splitArray)){ return 0; } } }

: 实现shell程序,要求在第2版的基础上,添加如下功能 实现管道

$ cat /etc/passwd | wc -l 实现管道和文件重定向 $ cat 3 2 1 3 2 1

$ cat < | sort | uniq | cat > $ cat 1 2 3 思路:

首先读取用户输入,以“|”为分隔符将输入分割成字符串数组,然后在一个while循环中依次执行下面的动作:代码中通过pipe()函数来创建管道,创建之后父进程和子进程一个只能向管道写内容,一个只能向管道读内容。然后利用dup()函数来把进程的输入流或者输出流重定向到管道里,这样就能实现管道的操作。实现的时候注意可以使用多个“|”来迭代进行管道操作,需要使用一个循环来处

理。用system执行每一条命令,同时还要注意最后一个操作的输出流是标准输出(即屏幕),不需要重定向到管道里,需要特殊处理一下。

源代码: #include <> #include <> #include <> #include <> #include #include #include <> #define LEN 256 #define WIDTH 256 #define HEIGHT 10

void split(char source[],char dest[HEIGHT][WIDTH]) { char *p;

p=strsep(&source,\"|\"); int i=0;

for(i=0;p[i]!='\\0';i++){ dest[0][i]=p[i]; }

dest[0][i]='\\0'; while(p){

p=strsep(&source,\"|\"); if(p){

for(i=0;p[i]!='\\0';i++){ dest[j][i]=p[i]; }

dest[j][i]='\\0'; j++; } } } main(){

char command[LEN];

char splitArray[HEIGHT][WIDTH]={{'\\0'}}; printf(\"%s\gets(command);

split(command,splitArray); int i=0;

for(i=0;splitArray[i][0]!='\\0';i++){ puts(splitArray[i]); } int p[2]; int j=0;

for(j=0;splitArray[j+1][0]!='\\0';j++){ if (fork() == 0) { . = PI/4

主线程创建1个辅助线程 主线程计算级数的前半部分 辅助线程计算级数的后半部分

主线程等待辅助线程运行結束后,将前半部分和后半部分相加 思路:

计算公式前1000项,主线程计算前5000项,子线程计算后5000项,主进程等待子进程结束,通过pthread_join(sub,(void **)&result);的result参数获取子进程计算结果再相加即可。

源代码: #include<> #include<> #include<> #include<> #define LEN 10000 struct result{ float sum; };

void *subThread(){ int i; float j;

struct result *result;

float sum1=0,sum2=0,sum=0; for(i=LEN/2+1;i<=LEN;i++){ j=i; if(i%2==0){ sum1+=1/(2*j-1); } tart=0;

myparams[0].end=0;

for(i=1;i<=thread_num-1;i++){ struct param *myparam; myparam=&myparams[i];

myparam->start=myparams[i-1].end+1;

myparam->end=myparams[i].start+(LEN/thread_num)-1; pthread_create(&workers[i-1],NULL,compute,myparam);

}

myparams[thread_num].start=myparams[thread_num-1].end+1;

myparams[thread_num].end=LEN; pthread_create(&workers[thread_num-1],NULL,compute,&myparams[thread_num]);

int j; float sum=0;

for(j=0;j struct result *myresult;

pthread_join(workers[j],(void **)&myresult); sum+=myresult->sum; free(myresult); }

printf(\"%f\\n\return 0; }

: 多线程排序

主线程创建一个辅助线程

主线程使用选择排序算法对数组的前半部分排序 辅助线程使用选择排序算法对数组的后半部分排序

主线程等待辅助线程运行結束后,使用归并排序算法归并数组的前半部分和后半部分

思路:

主线程排序数组的前半部分,辅助线程排序后半部分,pthread_create(&worker_id,NULL,&sort,&pa);

中pa传递的是数组的首地址,主线程等辅助线程结束后,再调用merge将数组合并为有序。

源代码: #include<>

#include<> #include<> #include<> #define LEN 10

int array[LEN]={0,3,8,6,2,9,5,4,1,7}; struct param{ int *arr; };

void *sort(void *arg){ struct param *mypa; mypa=(struct param *)arg; int i=0; int j=0; int min=0; int temp=0;

for(i=LEN/2;i min=i;

for(j=i;j

if(mypa->arr[min]>mypa->arr[j])min=j; }

temp=mypa->arr[min]; mypa->arr[min]=mypa->arr[i]; mypa->arr[i]=temp; } }

void merge(){ int i=0; int a[LEN/2]; int b[LEN/2]; for(i=0;i<=\"\" p=\"\">

a[i]=array[i]; b[i]=array[i+LEN/2]; }

/* for(i=0;i<=\"\" p=\"\"> printf(\"%d\\n\}*/ int tm=0; int ti=0,tj=0; while(ti<=\"\" p=\"\"> if(a[ti] array[tm]=a[ti]; ti++; }else{

array[tm]=b[tj]; tj++; } tm++; } }

int main() {

struct param pa; =array;

int ti=0,tj=0,tmin=0; for(ti=0;ti<=\"\" p=\"\"> tmin=ti;

for(tj=ti;tj<=\"\" p=\"\">

if(array[tmin]>array[tj])tmin=tj; }

int temp=array[tmin];

array[tmin]=array[ti]; array[ti]=temp; }

pthread_t worker_id;

pthread_create(&worker_id,NULL,&sort,&pa); pthread_join(worker_id,NULL); merge(); int i=0;

for(i=0;i printf(\"%d\\n\} }

: 使用条件变量解决生产者、计算者、消费者问题 系统中有3个线程:生产者、计算者、消费者 系统中有2个容量为4的缓冲区:buffer1、buffer2

生产者生产'a'、'b'、'c'、‘d'、'e'、'f'、'g'、'h'八个字符,放入到buffer1

计算者从buffer1取出字符,将小写字符转换为大写字符,放入到buffer2

消费者从buffer2取出字符,将其打印到屏幕上 思路:

类似于生产者和消费者,在问题中,生产者、计算者相对应buffer1是生产者、消费者,二者互斥的进入buffer1,并且当buffer1满时,生产者等待,当buffer1空时,且计算值要从中取数据时,计算者等待。同理,计算者、消费者相对应buffer2是生产者和消费者,二者互斥的进入buffer2,当buffer2满时,且计算者要向其中放入数据时,计算者应等待,当buffer2空时,消费者应等待。

源代码: #include <> #include <>

#define CAPACITY 4 int buffer1[CAPACITY]; int buffer2[CAPACITY]; int in1; int out1; int in2; int out2;

int buffer2_is_empty() {

return in2 == out2; }

int buffer2_is_full() {

return (in2 + 1) % CAPACITY == out2; } int buffer1_is_empty() {

return in1 == out1; }

int buffer1_is_full() {

return (in1 + 1) % CAPACITY == out1; } int get_item() { int item;

item = buffer2[out2];

out2 = (out2 + 1) % CAPACITY; return item; }

void put_item(int item) {

buffer1[in1] = item; in1 = (in1 + 1) % CAPACITY; }

int cal_get_item()

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- efsc.cn 版权所有

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务