您好,欢迎访问三七文档
操作系统实践报告多进程题目sh1.c:实现shell程序,要求具备如下功能支持命令参数$echoarg1arg2arg3$ls/bin/usr/bin/home实现内置命令cd、pwd、exit$cd/bin$pwd/bin思路:说明:首先设置一个死循环模仿shell终端,读取用户的输入,并且根据空格将输入拆分成字符串数组,然后调用excute这个子函数进行处理。1.echo根据数组第一个元素来判断命令是什么,判断出是ehco后,fork一个新的进程,将其后的内容一个个输出出来,并且父进程等待子进程退出后再执行,确保输出在屏幕上时不被打断。2.ls读取用户输入并且根据拆分的数组判断出是ls命令后,fork一个新的进程,调用execlp函数将/bin/ls下的ls程序装入子进程并将拆分的数组参数部分传递给ls即可,同样的,父进程等待子进程退出,确保输出在屏幕上不被打断。3.cd同样是根据输入并拆分成数组后判断出是cd命令后,fork一个新的进程,然后调用chdir并将拆分数组的参数部分传递给chdir作为实参即可。4.pwd同样是根据输入并拆分成数组后判断出是pwd命令后,fork一个新的进程,然后调用system(pwd)即可,此命令也可以用来验证上面的cd命令是否正确执行。5.exit根据用户输入逼格拆分的数组判断出是exit命令后,excute子函数返回-1,在循环中检测excute的返回值,如果是-1则直接return,退出模仿的shell终端。sh2.c:实现shell程序,要求在第1版的基础上,添加如下功能实现文件重定向$echohellolog$catlogHello思路:接sh1.c的描述,若判断出是echo命令后,要再次判断拆分的字符串数组中有无“”出现,如果有,则把“”之前、echo之后的内容作为输出,把“”之后到“”之后的第一个空白字符作为文件名,fopen创建文件并fwrite将输出内容输出到该文件中,并关闭文件。sh1.c和sh2.c的源代码:#includestdio.h#includeunistd.h#includefcntl.h#includestring.h#includesys/types.h#includesys/wait.h#includestdlib.h#defineLEN256#defineWIDTH256#defineHEIGHT10voidsplit(charsource[],chardest[HEIGHT][WIDTH]){char*p;p=strsep(&source,);inti=0;for(i=0;p[i]!='\0';i++){dest[0][i]=p[i];}dest[0][i]='\0';intj=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++;}}}intexecute(charcomm[HEIGHT][WIDTH]){if(strcmp(comm[0],echo)==0){intpid=fork();if(pid==0){inti=0;intis=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+);intj=0;for(j=1;ji;j++){fseek(fp,0,SEEK_END);fwrite(comm[j],strlen(comm[j]),1,fp);}fclose(fp);}else{intj=0;for(j=1;comm[j][0]!='\0';j++){printf(%s,comm[j]);printf();}printf(\n);}}else{intstatus;wait(&status);}}elseif(strcmp(comm[0],ls)==0){intpid=fork();if(pid==0){if(comm[1][0]=='\0'){execlp(/bin/ls,ls,./,NULL,NULL,NULL);}else{execlp(/bin/ls,ls,comm[1],NULL,NULL,NULL);}}else{intstatus;wait(&status);}}elseif(strcmp(comm[0],cd)==0){intpid=fork();if(pid==0){chdir(comm[1]);}else{intstatus;wait(&status);}}elseif(strcmp(comm[0],pwd)==0){intpid=fork();if(pid==0){system(pwd);}else{intstatus;wait(&status);}}elseif(strcmp(comm[0],exit)==0){return-1;}return1;}intmain(){while(1){charcommand[LEN];charsplitArray[HEIGHT][WIDTH]={{'\0'}};printf(%s,);gets(command);split(command,splitArray);inti=0;if(-1==execute(splitArray)){return0;}}}sh3.c:实现shell程序,要求在第2版的基础上,添加如下功能实现管道$cat/etc/passwd|wc-l实现管道和文件重定向$catinput.txt321321$catinput.txt|sort|uniq|catoutput.txt$catoutput.txt123思路:首先读取用户输入,以“|”为分隔符将输入分割成字符串数组,然后在一个while循环中依次执行下面的动作:代码中通过pipe()函数来创建管道,创建之后父进程和子进程一个只能向管道写内容,一个只能向管道读内容。然后利用dup()函数来把进程的输入流或者输出流重定向到管道里,这样就能实现管道的操作。实现的时候注意可以使用多个“|”来迭代进行管道操作,需要使用一个循环来处理。用system执行每一条命令,同时还要注意最后一个操作的输出流是标准输出(即屏幕),不需要重定向到管道里,需要特殊处理一下。源代码:#includestdio.h#includeunistd.h#includefcntl.h#includestring.h#includesys/types.h#includesys/wait.h#includestdlib.h#defineLEN256#defineWIDTH256#defineHEIGHT10voidsplit(charsource[],chardest[HEIGHT][WIDTH]){char*p;p=strsep(&source,|);inti=0;for(i=0;p[i]!='\0';i++){dest[0][i]=p[i];}dest[0][i]='\0';intj=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++;}}}main(){charcommand[LEN];charsplitArray[HEIGHT][WIDTH]={{'\0'}};printf(%s,);gets(command);split(command,splitArray);inti=0;for(i=0;splitArray[i][0]!='\0';i++){puts(splitArray[i]);}intp[2];pipe(p);intj=0;for(j=0;splitArray[j+1][0]!='\0';j++){if(fork()==0){//Childprocessclose(0);close(p[0])close(p[1]);dup(p[0]);system(splitArray[j]);}else{//Parentprocessclose(1);close(p[0])close(p[1]);dup(p[1]);system(splitArray[j+1]);}}}多线程题目pi1.c:使用2个线程根据莱布尼兹级数计算PI莱布尼兹级数公式:1-1/3+1/5-1/7+1/9-...=PI/4主线程创建1个辅助线程主线程计算级数的前半部分辅助线程计算级数的后半部分主线程等待辅助线程运行結束后,将前半部分和后半部分相加思路:计算公式前1000项,主线程计算前5000项,子线程计算后5000项,主进程等待子进程结束,通过pthread_join(sub,(void**)&result);的result参数获取子进程计算结果再相加即可。源代码:#includestdio.h#includeunistd.h#includestdlib.h#includepthread.h#defineLEN10000structresult{floatsum;};void*subThread(){inti;floatj;structresult*result;floatsum1=0,sum2=0,sum=0;for(i=LEN/2+1;i=LEN;i++){j=i;if(i%2==0){sum1+=1/(2*j-1);}//printf(%f\n,sum2);if(i%2==1){sum2+=1/(2*j-1);}}//printf(%f\n,sum1);sum=sum2-sum1;//printf(%f\n,sum);//printf(%f\n,sum);result=malloc(sizeof(result));result-sum=sum;returnresult;}intmain(){inti;floatj;floatsum1=0,sum2=0,sum=0;for(i=1;i=LEN/2;i++){j=i;if(i%2==0){sum1+=1/(2*j-1);}if(i%2==1){sum2+=1/(2*j-1);}}sum=sum2-sum1;//printf(%f\n,sum);pthread_tsub;pthread_create(&sub,NULL,subThread,NULL);structresult*result;pthread_join(sub,(void**)&result);sum+=result-sum;printf(%f\n,sum);return0;}pi2.c:使用N个线程根据莱布尼兹级数计算PI与上一题类似,但本题更加通用化,能适应N个核心,需要使用线程参数来实现主线程创建N个辅助线程每个辅助线程计算一部分任务,并将结果返回主线程等待N个辅助线程运行结束,将所有辅助线程的结果累加思路:设计算公式前1000项,读取用户输入的线程数目N,通过pthread_create(&workers[i-1],NULL,compute,myparam);产生N个线程,并且通过myparam设置每一个线程计算的起始项和终止项,通过pthread_join(workers[j],(void**)&myresult);等待每个线程结束并通过result获取结果,将结果相加即可。源代码:#includestdlib.h#includestdio.h#includepthread.h#includeunistd.h#defineLEN10000#defineMAX_WORKERS100struct
本文标题:操作系统实践报告
链接地址:https://www.777doc.com/doc-5537872 .html