第三次实验进程的创建Word格式文档下载.docx

上传人:b****5 文档编号:21515824 上传时间:2023-01-30 格式:DOCX 页数:13 大小:133.67KB
下载 相关 举报
第三次实验进程的创建Word格式文档下载.docx_第1页
第1页 / 共13页
第三次实验进程的创建Word格式文档下载.docx_第2页
第2页 / 共13页
第三次实验进程的创建Word格式文档下载.docx_第3页
第3页 / 共13页
第三次实验进程的创建Word格式文档下载.docx_第4页
第4页 / 共13页
第三次实验进程的创建Word格式文档下载.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

第三次实验进程的创建Word格式文档下载.docx

《第三次实验进程的创建Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《第三次实验进程的创建Word格式文档下载.docx(13页珍藏版)》请在冰豆网上搜索。

第三次实验进程的创建Word格式文档下载.docx

甘肃政法学院实验管理中心印制

实验题目

进程的创建

小组合作

姓名

班级

学号

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()函数阻塞子进程。

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 总结汇报 > 实习总结

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1