《操作系统》课程设计指导一
-----进程管理设计
2006/6/20 沈奕鹏 管建军
一、设计目的
(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.课程设计结束,要上交课程设计报告一份和含有程序的软盘一张。