第三次实验进程的创建Word格式文档下载.docx
《第三次实验进程的创建Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《第三次实验进程的创建Word格式文档下载.docx(13页珍藏版)》请在冰豆网上搜索。
甘肃政法学院实验管理中心印制
实验题目
进程的创建
小组合作
否
姓名
班级
学号
200981010142
一、实验目的
1.理解和掌握UNIX(和Linux)进程控制系统调用的功能。
3.理解进程的调度和执行
2.理解如何创建一个进程、改变进程执行程序、进程的终止和父子进程同步
3.提高对进程控制系统调用的编程能力
二.实验环境
1.操作系统WindowsXP
2.装有虚拟机Linux的系统
三、实验内容与步骤
1.fork()函数
用fork()函数创建进程时,语句调用系列如下:
#include<
sys/types.h>
unistd.h>
Pit_tfork(void);
fork()函数是一个单调用双返回的函数,也就是说,该函数有父进程调用,执行时,在父进程中返回子进程标识,在子进程中返回0。
fork()调用后,子进程是父进程的一个复制。
都是从fork()调用语句开始执行。
编写一个程序,使用fork()函数创建一个子进程,程序运行时,父进程输出两个变量的值,子进程将父进程的两个变量值改变后输出,并分析程序运行结果产生的原因。
代码如下所示:
stdio.h>
intglob=3;
intmain(void)
{
pid_tpid;
intloc=3;
printf("
beforefork();
glod=%d,loc=%d.\n"
glob,loc);
if((pid=fork())<
0)
{
fork()error.\n"
);
exit(0);
}
elseif(pid==0)
glob++;
loc--;
childprocesschangesglobandloc:
\n"
else
wait(0);
parentprocessdoesn'
tchangetheglobandloc:
\n"
glob=%d,loc=%d\n"
}
2.vfork()函数
用vfork()函数创建进程时,语句调用序列如下;
用vfork()函数创建进程是,通常使用exec()函数紧跟其后,以便为新创建的进程指派另一个可执行程序,
用vfork()函数系统调用,观察运行结果,分析结果产生的原因,比较fork和vfork的区别。
代码如下:
intloc=3;
if((pid=vfork())<
{
vfork()error\n"
childprocesschangestheglobandloc\n"
}
printf("
tchangetheglobandloc\n"
glob=%d,val=%d\n"
3.给进程指定一个新的运行程序的函数exec().
一个进程的调用exec()函数来运行一新程序。
之后该进程的代码段.数据段和堆栈段被新程序所代替。
新程序从自己的main()函数开始进行。
编写一个程序,运行时一个进程调用exec()函数来运行一个新的程序。
建立print1.c文件,编译生成可执行文件print1是主程序file4.c中exec函数指派的可执行程序名,将传递给程序的参数和环境变量进行输出。
其代码如下:
printe1.c代码:
intmain(intargc,char*argv[])
intn;
char**ptr;
externchar**environ;
for(n=0;
n<
argc;
n++)
printf("
argv[%d]:
%s\n"
n,argv[n]);
for(ptr=environ;
*ptr!
=0;
ptr++)
*ptr);
file4.c代码如下:
sys/wait.h>
char*env_list[]={"
USER=root"
"
PATH=/root/"
NULL};
intmain()
forkerror!
exit(0);
if(execle("
/root/print1"
print1"
arg1"
arg2"
(char*)0,env_list)<
printf("
execleerror!
if((waitpid(pid,NULL,0))<
WAITERROR!
if(execlp("
(char*)0)<
4.进程终止函数exit()。
在Linux系统中,进程通过执行系统调用exit()来终止自己。
exit()调用的两个例子,观察结果,进一步理解exit()函数,代码如下:
main()
thisisaexitsystemcall!
!
thissentenceneverbedisplayen:
thisisa_exit_testsystemcall!
contentinbuffer"
5.wait()函数和sleep()函数。
编写一个父子进程同步的实例,并分析结果,改变其sleep()的参数,观察结果,理解体会wait()和sleep()函数各自的功能。
intpid1;
if(pid1=fork())
if(fork())
parent'
scontext,\n"
swaitingthechild1terminate,\n"
swaitingthechild2terminate,\n"
parentterminates,\n"
child2'
sleep(5);
child2terminates,\n"
if(pid1==0)
child1'
sleep(10);
child1terminates,\n"
6.编写一段程序,父进程使用fork()创建两个子进程,利用输出函数putchar父进程显示字符”a”,两个子进程分别显示“b”和“c”。
多次运行该程序,观察并记录屏幕上的显示结果,分析原因。
intpid;
if(pid=fork())
parentprocessis\n"
putchar('
A'
child2processis\n"
C'
else
if(pid==0)
child1processis\n"
B'
四、实验过程与分析
一,fork()函数调用运行结果如下图:
分析:
该程序可能产生二种结果,第一种:
root@localhostroot]#./file1
beforefork():
glob=3,loc=3.
glob=4,loc=2
glob=3,loc=3
第二种:
当程序运行到if((pid=fork())<
0)时,表示创建进程失败,输出“fork()error”,程序故障中止。
创建成功后,程序运行时产生两个进程,有main函数产生一个父进程以及程序执行时调用fork产生一个子进程。
当执行到fork后形成两个并发进程,第一种情况,父进程先执行,子进程后执行,而第二种恰好相反。
2.vfork()函数调用运行结果如下图:
运行结果只有一种,由于vfork()函数与fork()函数的区别是:
fork()函数执行时不对父子进程次序进行任何限制。
而vfork()函数调用后,子进程先运行,父进程挂起,直到子进程exit(0)调用,子进程结束,父进程才激活执行。
所以运行结果只有一种。
3.函数exec()的程序运行结果如下图:
先运行子进程print1.c,生成子进程可执行文件,在运行源程序,当运行到execle()时,调用子进程的可执行文件的路径,传递的参数有可执行程序的路径名、程序所需参数及程序执行的环境变量。
故执行结果为arg[0]:
print1(即程序),arg[1]:
arg1,arg[2]:
arg2(即参数)和USER=root,PATH=/root/(即环境变量)。
4.exit()函数系统调用运行结果如下图:
系统调用exit()来终止自己,所以在第一个程序中:
当程序执行到exit(0)时,程序将结束,不再执行下一句,所以输出只有一条语句。
5.wait()和sleep()系统调用。
运行结果如下图:
该程序是父进程首先创建一个子进程,若成功,再创建另一个子进程,之后三个进程并发执行,它们运行是随机的,上图是其中的一种情况,由运行结果可知程序的运行顺序,子进程创建成功后,首先开始子进程1执行,当执行到sleep(10)时,子进程1被阻塞,接着执行子进程2,当执行到sleep(5)时,同样也被阻塞,此时跳到父进程中执行,执行到第一个wait(0)时被阻塞,此时由于子进程2的睡眠时间比子进程1的时间短,系统此时唤醒了子进程2,当子进程2执行exit(0)后结束子进程2,父进程再次被唤醒,继续执行父进程,当执行到第二个wait(0)时再次被阻塞,此时跳到子进程1执行,直到运行到exit(0)后退出子进程1,父进程再次继续执行直到结束。
若将子进程1,2的sleep()都改为sleep(0)时的执行结果如下图所示
此时子进程1和2将不会被sleep()阻止,先将子进程1运行完后,在运行子进程2,最后运行父进程,直到结束。
在将子进程1,2的sleep()都改为sleep(5)时的执行结果如下图所示
该程序和第一个程序基本一样,先运行子进程1和子进程2,在跳回父进程,唯一不同的是在父进程中当运行到wait(0)时,因为子进程1和2sleep睡眠时间一样,此时系统调用了子进程1,再次调用子进程2,所以运行结果如上图。
六,运行结果如下图:
如上图可知产生了一种结果:
先输出进程1,在运行进程2,最后运行父进程,即BCA。
由程序可知函数fork创建子进程后,形成了3个并发进程,每个进程执行都用可能。
putchar输出语句时间很短,产生的结果不止上面一种,还有可能是ABC,CAB,CBA......等几种结果。
注释掉所有printf的输出语句,在快速运行后产生结果如下:
五、实验总结
本实验通过利用系统调用fork()和vfork()创建子进程,创建成功后,父进程返回的是被创建子进程的标识,给子进程自己返回的是0,创建失败时,返回给父进程的是-1,以及fork()和vfork()的区别,fork创建后子进程和父进程是并发执行的。
vfork()创建成功后,父进程被挂起,子进程先执行,直到子进程结束后,在执行父进程。
系统调用exec()函数是用来进程调用来运行一个新程序,之后该进程的代码段.数据段和堆栈段被新程序所代替。
系统调用exit()函数是来终止自己进程,wait()函数是用来阻塞父进程来等待子进程,实现了父子进程的同步,而sleep()函数阻塞子进程。