}
return0;
}
三、主要仪器设备及耗材
Ubuntu操作体统
Vi编辑器
G++编译
第二部分:
实验调试与结果分析(可加页)
一、调试过程(包括调试方法描述、实验数据记录,实验现象记录,实验过程发现的问题等)
(1)【进程的创建】
编写一段程序,使用系统调用fork()创建两个子进程,当此进程运行时,在系统中有一个父进程和两个子进程活动,让每一个进程在屏幕上显示一个字符,父进程显示字符“a”;子进程分别显示字符“b”和字符“c”,试观察记录屏幕上的显示结果,并分析原因。
【源程序】:
#include
intmain()
{
intp1,p2;
while((p1=fork())==-1);
if(p1==0)//第一子进程
putchar('b');
else{
while((p2=fork())==-1);
if(p2==0)
putchar('c');//第二子进程
else
putchar('a');//父进程
}
return0;
}
运行多次:
主要输出有bca,偶尔输出cab和cba,abc,bac,acb…
会有如此多种不同输出,主要是因为fork()生成的子进程和父进程是并行运行的,所以先运行哪个进程是由系统的调度算法决定的,ubuntu9.04很大概率系统会先输出bca是因为ubuntu9.04在fork()运行之后很大概率先运行子进程,再运行父进程。
当然也有可能先运行父进程后子进程,再加上进程间的并发性;导致了输出的多样性。
输出次序带有随机性。
。
(2)【进程的控制】
修改已编写的程序,将每个进程输出一个字符改为每个进程输出一句
话,在观察程序执行时屏幕上出现的现象,并分析原因。
【源代码】:
#include
intmain(){
intp1,p2;
while((p1=fork())==-1);
if(p1==0);第一个子进程
printf("Child1isrunning!
\n");
else{
while((p2=fork())==-1);
if(p2==0);第二子进程
printf("Child2isrunning!
\n");
else;父进程
printf("Fatherisrunning!
\n");
}
return0;
}
运行多次,大部分运行后输出:
Child1isrunning!
Child2isrunning!
Fatherisrunning!
少数输出:
Child2isrunning!
Child1isrunning!
Fatherisrunning!
Fatherisrunning!
Child1isrunning!
Child2isrunning!
……
理论上是有6种不同的结果,还是由于系统的调度算法,程序的并发性影响;但由于函数printf()在输出字符串时不会被中断,因此,字符串内部字符顺序输出不变。
所以与打印单字符的结果相同。
创建进程,使用exec函数族使子进程执行新的目标程序,观察并分析
出现的现象。
【源代码】:
#include
#include
intmain()
{
printf("===systemcallexecltesting===\n");
execlp("date","date",0);
printf("execerror!
\n");
return0;
}
输出:
===systemcallexecltesting===
2009年12月04日星期五21:
35:
18CST
输出结果分析:
execlp是一种exec函数,当进程调用一种exec函数时,用指定的目标进程更好进程的执行映像。
Exec调用成功后,调用进程的正文段被指定的文件的正文段所覆盖。
调用成功时,exec不返回,从而不执行exec以后的所有语句,所以本例就只有输出“2009年12月04日星期五21:
35:
18CST”的情况。
如果调用失败,返回-1,执行剩余指令。
(3)【进程信号处理】
编写程序使用系统调用fork()创建两个子进程,再用系统调用singal()让父进程捕捉键盘上来的中断信号(即按Ctrl+c键);当捕捉到中断信号后,父进程用系统调用Kill()向两个子进程发出信号,子进程捕捉到信号后分别输出下列信息后终止:
ChildProcess11isKilledbyParent!
ChildProcess12isKilledbyParent!
父进程等待两个子进程终止后,输出如下的信息后终止:
ParentProcessisKilled!
【源代码】:
#include
#include
intwait_mark;
voidwaiting()
{
while(wait_mark==1);
}
voidstop()
{
wait_mark=0;
}
intmain()
{
intp1,p2;
while((p1=fork())==-1);
if(p1==0);第一个子进程
{
wait_mark=1;
signal(SIGINT,SIG_IGN);
signal(16,stop);
waiting();
lockf(1,1,0);;加锁
printf("ChildProcess11isKilledbyParent!
\n");
lockf(1,0,0);;解锁
exit(0);
}
Else
{
while((p2=fork())==-1);
if(p2==0);第二个子进程
{
wait_mark=1;
signal(SIGINT,SIG_IGN);
signal(17,stop);
waiting();
lockf(1,1,0);;加锁
printf("ChildProcess12isKilledbyParent!
\n");
lockf(1,0,0);;解锁
exit(0);
}
Else;父进程
{
wait_mark=1;
signal(SIGINT,stop);
waiting();
kill(p1,16);
kill(p2,17);
wait(0);
wait(0);
printf("ParentProcessisKilled!
\n");
exit(0);
}
}
}
输出结果有两种:
ChildProcessllisKilledbyParent!
ChildProcessl2isKilledbyParent!
ParentprocessisKilled!
ChildProcessl2isKilledbyParent!
ChildProcessllisKilledbyParent!
ParentprocessisKilled!
二、实验结果及分析(包括结果描述、实验现象分析、影响因素讨论、综合分析和结论等)
三、实验小结、建议及体会
通过这次实验掌握Linux系统中进程控制原语fork的使用方法。
同时发现自己对Linux有很多的不熟悉的地方,在以后会进一步加强。