《作業系統》課程設計指導——程序管理設計
一、設計目的
(1)加深對程序概念的理解,明確程序和程式的區別。
(2)進一步認識併發執行的實質。
(3)分析程序爭用資源的現象,學習解決程序互斥的方法。
(4)瞭解Linux系統中程序通訊的基本原理。
二、設計內容
1)程序的軟中斷通訊
①編制一段程式,使其實現程序的軟中斷通訊。
要求:使用系統呼叫fork()建立兩個子程序,再用系統呼叫signal()讓父程序捕捉
鍵盤上來的中斷訊號(即按DEL鍵);當捕捉到中斷訊號後,父程序用系統呼叫Kill()向兩個子程序發出訊號,子程序捕捉到訊號後分別輸出下列資訊後終止:
Child Proeess 1 is Killed by Parent!
Child Process 2 is Killed by Parent!
父程序等待兩個子程序終止後,輸出如下的資訊後終止:
Parent Process is Killed!
②在上面的程式中增加語句signal(SIGINT,SIG_IGN)和signal(SIGQUIT,SIG _IGN),觀察執行結果,並分析原因。
2)程序的管道通訊
編制一段程式,實現程序的管道通訊。
使用系統呼叫pipe()建立一條管道線;兩個子程序P1和P2分別向管道各寫一句話:
Child l is sending a message!
Child 2 is sending a message!
而父程序則從管道中讀出來自於兩個子程序的資訊,顯示在螢幕上。
要求父程序先接收子程序P1發來的訊息,然後再接收子程序P2發來的訊息。
三、指導步驟
1)程序的軟中斷通訊
<任務1>
編制一段程式,使用系統呼叫fork()建立兩個子程序,再用系統呼叫signal()讓父程序捕捉鍵盤上來的中斷訊號(即按Del鍵),當捕捉到中斷訊號後,父程序用系統呼叫kill() 向兩個子程序發出訊號,子程序捕捉到訊號後,分別輸出下列資訊後終止:
child process l is killed by parent!
child process 2 is killed by parent!
父程序等待兩個子程序終止後,輸出以下資訊後終止:
parent process is killed!
(程式)
/*e-1-31*/
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
int wait_flag;
void stop();
main() {
int pid1,pid2;
signal(3,stop); //or signal(14,stop);
while((pid1=fork())==-1);
if(pid1>0) {
while((pid2=fork())==-1);
if(pid2>0) {
// wait_flag=1;
sleep(5);
kill(pid1,16);
kill(pid2,17);
wait(0);
wait(0);
printf("Parent process is killed !!\n");
exit(0);
}
else {
// wait_flag=1;
signal(17,stop);
printf("Child process 2 is killed by parent !!\n");
exit(0);
}
}
else {
// wait_flag=1;
signal(16,stop);
printf("Child process 1 is killed by parent !!\n");
exit(0);
}
}
void stop() {
wait_flag=0;
}
(執行結果)
child process 1 is killed by parent!
child process 2 is killed by parent!
Parent process is killed!
分析
(1)上述程式中,實用函式signal()都放在一段程式的前面部位,而不是在其他接收訊號處。這是因為signal()的執行只是為程序指定訊號量16或17的作用,以及分配相應的與 stop()過程連結的指標。從而signal()函式必須在程式前面部分執行。
(2)該程式段前面部分用了兩個wait(0),為什麼?請讀者思考。
(3)該程式段中每個程序退出時都用了語句exit(0),為什麼?請讀者思考。
<任務2>
在上面任務1中,增加語句signal(SIGINT,SIG_IGN)和語句signal(SIGQUIT, SIG_IGN),觀察執行結果,並分析原因。這裡signal(SIGINT,SIG_IGN)和signal(SIGQUIT,SIG_IGN)分別為忽略'Del'鍵訊號以及忽略中斷訊號。
(程式)
/*e-1-32*/
#include<unistd.h>
#include<signal.h>
#include<stdio.h>
int pid1,pid2;
int EndFlag=0;
//pf1=0;
//pf2=0;
void IntDelete()
{
kill(pid1,10);
kill(pid2,12);
EndFlag=1;
}
void Int1()
{
printf("child process 1 is killed ! by parent/n");
exit(0);
}
void Int2()
{
printf("child process 2 is killed ! by parent/n");
exit(0);
}
waiting()
{ while(EndFlag==0);}
main()
{
//int exitpid;
signal(SIGINT,SIG_IGN);
signal(SIGQUIT,SIG_IGN);
while((pid1=fork())==-1);
if(pid1==0)
{
//signal(SIGINT,SIG_IGN);
signal(10,Int1);
signal(SIGINT,SIG_IGN);
pause();
exit(0);
}
else
{
while((pid2=fork())==-1);
if(pid2==0)
{
//signal(SIGINT,SIG_IGN);
signal(12,Int2);
signal(SIGINT,SIG_IGN);
pause();
exit(0);
}
else
{
signal(SIGINT,IntDelete);
//waitpid(-1,&exitcode,0);
waiting();
printf("parent process is killed/n");
exit(0);
}
}
}
<執行結果>
請讀者將上述程式輸入計算機後,執行並觀察。
<分析> 由於忽略了中斷與退出訊號,程式會一直保持阻塞狀態而無法退出。
2)程序的管道通訊
(任務)
編制一段程式,實現程序的管道通訊。使用系統呼叫pipe()建立一條管道線。兩個子程序p1和p2分別向管道各寫一句話:
child 1 is sending message!
child 2 is sending message!
而父程序則從管道中讀出來自於兩個子程序的資訊,顯示在螢幕上。
(程式)
/*e-1-4*/
#include<unistd.h>
#include<signal.h>
#include<stdio.h>
int pid1,pid2;
main()
{
int fd[2];
char OutPipe[100],InPipe[100];
pipe(fd);
while((pid1=fork())==-1);
if(pid1==0)
{
lockf(fd[1],1,0);
sprintf(OutPipe,"child 1 process is sending message!");
write(fd[1],OutPipe,50);
sleep(5);
lockf(fd[1],0,0);
exit(0);
}
else
{
while((pid2=fork())==-1);
if(pid2==0)
{
lockf(fd[1],1,0);
sprintf(OutPipe,"child 2 proeess is sending message!");
write(fd[1],OutPipe,50);
sleep(5);
lockf(fd[1],0,0);
exit(0);
}
else
{
wait(0);
read(fd[0],InPipe,50);
printf("%s/n",InPipe);
wait(0);
read(fd[0],InPipe,50);
printf("%s/n",InPipe);
exit(0);
}
}
}
(執行結果)
child 1 is sending message!
child 2 is sending message!
(分析)
請讀者自行完成。
二、說明:
1.教材“計算機作業系統教程第二版習題解答與實驗指導-張堯學”書,P76實驗1中(3)和(4),有多個錯誤,這正是要求同學進行分析、排錯和除錯,這也是考核學生的實際動手能力。一定要仔細哦。
2.一定要把自己的所有程式儲存在一張軟盤上,以供教師檢查。
3.課程設計結束,要上交課程設計報告一份和含有程式的軟盤一張。
——————————轉自風之子部落格專欄