本来就打算在实验课结束后把这学期的实验统统整理一遍,加深一下印象,后来随着考试周的临近,时间太紧,就放弃了,然后暑假开始又有各种各样的事情,虽然不至于忙得不可开交,但也着实不想腾出功夫写写总结,最近有个项目快要完成了,趁着中间松了一口气,把之前的想法整理一下,一方面帮助自己记起更多的知识,避免刚学完就忘掉,另一方面也希望这些实验能够帮帮助一些初学者吧。
操作系统这门课老师很幽默,但实验好多人都不会,可能大家都在忙自己的事情,没时间理会实验这件小事。我当然不希望这些实验资料能够直接帮助我的学弟学妹们混过实验分,但如果可以从这些比较基础的代码中得到更好的思路或想法,我觉得也算是抛砖引玉了。
接下来我会逐步地把我做过的操作系统的实验整理上来,当然不是纯代码。中间如果我记得没错的话,有几个实验还是有bug的,不过交实验的时候老师被我糊弄过去了。。^--^。。希望有人能够有时间共同交流一下实验代码。
好,废话不多说,第一个实验很简单,进程控制实验。
题目:
编写一个多进程并发执行程序。父进程首先创建一个执行 ls 命令的子进程然后再创建一个执行 ps 命令的子进程,并控制ps 命令总在 ls 命令之前执行。
我的思路;
首先,很显然,需要用到操作系统中最熟悉的函数:fork(),同时,控制命令执行的顺序,毫无疑问需要用到信号来控制,使用kill()函数。
我的实验代码:
fork()函数都应该很熟悉了,执行一次分别向父子进程返回两个不同的值,向父进程返回子进程的pid,向子进程返回0.
由于要使用kill函数,首先在头文件中定义一个函数指针,以及一个在子进程接受其他进程信号后需要执行的命令的函数。
#include <sys/types.h> #include <wait.h> #include <unistd.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> typedef void (*sighandler_t)(int); void showLs(){ execlp("/bin/ls","ls",NULL); printf("finished my 'ls' work"); }
然后,就是让父进程fork两个子进程,分别执行,且控制执行顺序,思路很简单,代码如下:
#include <sys/types.h> #include <stdio.h> #include <unistd.h> #include <wait.h> #include <stdlib.h> #include <signal.h> #include "exp1.h" int main(int argc,char* argv[]){ pid_t pid;//用于保存子进程进程号 pid = fork(); if(pid < 0){/*error */ fprintf(stderr,"Fork Failed"); exit(-1); }else if(pid == 0){ printf("I am child process %d to do ls.\n",getpid()); signal(SIGINT,(sighandler_t)showLs); //注册一个本进程处理键盘中断的函数 pause();//等待信号 }else if(pid > 0){ printf("This is parent process TO perform another fork\n"); //再一次fork() pid_t pid2; pid2 = fork(); if(pid2 < 0){/*fork 失败*/ fprintf(stderr,"The second fork failed\n"); exit(-1); }else if(pid2 == 0){/*资金进程执行ps命令*/ printf("pid to signal is %d\n",pid); printf("I am child process %d to do ps.\n",getpid()); execlp("/bin/ps","ps",NULL); }else{//等待子进程执行完毕之后,发送给执行ls命令的子进程信号 wait(NULL); printf("Finished my 'ps' work\n"); kill(pid,SIGINT);//向第一个子进程发送键盘中断信号 printf("Signal send\n"); } //等待所有子进程结束之后,退出 wait(NULL); printf("All Child Complete\n"); exit(0); } }
第一个实验就这么简单,重点是fork函数以及kill函数的使用,尤其是注意理解fork对父子进程的不同返回值,这对像我这样的初学者来说是很重要的。