本來就打算在實驗課結束后把這學期的實驗統統整理一遍,加深一下印象,后來隨着考試周的臨近,時間太緊,就放棄了,然后暑假開始又有各種各樣的事情,雖然不至於忙得不可開交,但也着實不想騰出功夫寫寫總結,最近有個項目快要完成了,趁着中間松了一口氣,把之前的想法整理一下,一方面幫助自己記起更多的知識,避免剛學完就忘掉,另一方面也希望這些實驗能夠幫幫助一些初學者吧。
操作系統這門課老師很幽默,但實驗好多人都不會,可能大家都在忙自己的事情,沒時間理會實驗這件小事。我當然不希望這些實驗資料能夠直接幫助我的學弟學妹們混過實驗分,但如果可以從這些比較基礎的代碼中得到更好的思路或想法,我覺得也算是拋磚引玉了。
接下來我會逐步地把我做過的操作系統的實驗整理上來,當然不是純代碼。中間如果我記得沒錯的話,有幾個實驗還是有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對父子進程的不同返回值,這對像我這樣的初學者來說是很重要的。
