-
实验目的
1.加深对进程概念的理解,明确进程和程序的区别;
2.进一步认识并发执行的实质;
3.分析进程争用资源的现象,学习解决进程互斥的方法。
-
实验内容和步骤
1. 复习课本关于进程控制和进程同步的内容,加深对进程管理概念的理解。
2.认真阅读附录部分,分析多个进程的运行情况,并学会如何解决进程互斥。
3.运行以下附录部分中给出的程序,查看自己运行的结果,并进行分析。
4.编写程序,要求见附录部分。
-
代码及运行结果分析
1.program1.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
int main(){
int i,j,k;
if (i=fork()){
j=wait(NULL);
printf("Parent Process!\n");
printf("i=%d,j=%d,k=%d\n",i,j,k);
}
else {
k=getpid();
printf("Child Process!\n");
printf("i=%d,k=%d\n\n",i,k);
}
}
分析:i的初始值为0,为子进程,if条件语句不满足,程序执行else语句,k等于子进程的ID,为5816,而后i=5816,执行if语句中内容,输出父进程的ID。
2.program2.c
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <unistd.h>
int main(){
int p1,p2;
while((p1=fork())==-1);
if(p1==0)
printf("b.My process ID is %d\n",getpid());
else{
while((p2=fork())==-1);
if(p2==0)
printf("c.My process ID is %d\n",getpid());
else
printf("a.My process ID is %d\n",getpid());
}
}
分析:p1=fork()运行未出错,p1=0不满足,p2=0不满足,输出子程序ID,而后p1值发生改变,不为0,p2=0,输出另一子程序ID,而后p2值发生改变,二者皆不为0,输出父进程ID。
3.program3.c
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
int main(){
int m,n,k;
m=fork();
printf("PID:%d\t",getpid());
printf("The return value of fork():%d\t\t",m);
printf("he\n");
n=fork();
printf("PID:%d\t",getpid());
printf("The return value of fork():%d\t\t",n);
printf("ha\n");
k=fork();
printf("PID:%d\t",getpid());
printf("The return value of fork():%d\t\t",k);
printf("ho\n");
return 0;
}
分析:程序中产生8个进程,根据每个进程ID相应的he、ha、ho结果,判断其是否有子进程。
4.program4.c
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
int main(){
int p1,p2,i;
while((p1=fork())==-1)break;
if(p1==0){
for(i=0;i<50;i++)
printf("son%d\n",i);
}
else{
while((p2=fork())==-1)break;
if(p2==0){
for(i=0;i<50;i++)
printf("daughter%d\n",i);
}
else{
for(i=0;i<50;i++)
printf("parent%d\n",i);
}
}
return 0;
}
分析:p1=fork(),产生一个子进程,p1初始值为0,输出for循环中的语句,之后p1的值改变,若p1>0,则执行else语句中的内容,进行for循环输出。
5.program5.c
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
int main(){
int m,n,k,l;
m=fork();
printf("PID:%d\t",getpid());
printf("The return value of fork():%d\t\t",m);
printf("he\n");
n=fork();
printf("PID:%d\t",getpid());
printf("The return value of fork():%d\t\t",n);
printf("ha\n");
if(m>0&&n>0){
k=fork();
printf("PID:%d\t",getpid());
printf("The return value of fork():%d\t\t",k);
printf("ho\n");
}
return 0;
}
分析:通过设置m>0&&n>0语句,使程序运行到第三个fork语句前进行条件判断,只对原始进程进行子进程的产生,由此实现题中的进程树。
6.program6.c
#include <stdio.h>
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
int main(){
int p1,p2,i;
int q1,q2;
while((p1=fork())==-1)break;
if(p1==0){
while(!q1&&!q2){
for(i=0;i<50;i++)
printf("son%d\n",i);
break;
}
}
else{
while((p2=fork())==-1)break;
if(p2==0){
q1=lockf(1,1,0);
for(i=0;i<50;i++)
printf("daughter%d\n",i);
q1=lockf(1,0,0);
}
else{
q2=lockf(1,1,0);
for(i=0;i<50;i++)
printf("parent%d\n",i);
q2=lockf(1,0,0);
}
}
return 0;
}
分析:通过lockf函数实现对其中一个进程对进行而对其他进程的锁定,使进程间相互不会被打断。
-
心得体会
通过本次实验,我更好地熟悉了Linux的各种操作,加深对进程概念的理解,明确进程和程序的区别,进一步认识并发执行的实质。了解进程争用资源的现象,学习解决进程互斥的方法。进一步掌握getpid()、sleep()、wait()、exit()等函数调用,在实践过程中认识到了自己的不足,在进程理论知识的一些短缺,并通过自己的亲身实践得到改正。