实验7编写多进程程序.docx
《实验7编写多进程程序.docx》由会员分享,可在线阅读,更多相关《实验7编写多进程程序.docx(11页珍藏版)》请在冰豆网上搜索。
![实验7编写多进程程序.docx](https://file1.bdocx.com/fileroot1/2022-10/10/fc59d968-6a8b-40d2-aff8-10623d6ebb4c/fc59d968-6a8b-40d2-aff8-10623d6ebb4c1.gif)
实验7编写多进程程序
实验7-编写多进程程序
实验七编写多进程程序
学生姓名:
李亚军学号:
6100412196
专业班级:
卓越计科121班
1.实验目的
通过编写多进程程序,使读者熟练掌握fork()、exec()、wait()和waitpid()等函数的使用,进一步理解在Linux中多进程编程的步骤。
2.实验内容
该实验有3个进程,其中一个为父进程,其余两个是该父进程创建的子进程,其中一个子进程运行“ls-l”指令,另一个子进程在暂停5s之后异常退出,父进程先用阻塞方式等待第一个子进程的结束,然后用非阻塞方式等待另一个子进程的退出,待收集到第二个子进程结束的信息,父进程就返回。
3.实验步骤
(1)画出该实验流程图
该实验流程图如图所示。
图实验7.1流程图
(2)实验源代码(multi_proc.c)
先看一下下面的代码,这个程序能得到我们所希望的结果吗,它的运行会产生几个进程?
请读者回忆一下fork()调用的具体过程。
答:
会产生四个进程
/*multi_proc_wrong.c*/
#include
#include
#include
#include
#include
intmain(void)
{
pid_tchild1,child2,child;
/*创建两个子进程*/
child1=fork();
child2=fork();
/*子进程1的出错处理*/
if(child1==-1)
{
printf("Child1forkerror\n");
exit
(1);
}
elseif(child1==0)/*在子进程1中调用execlp()函数*/
{
printf("Inchild1:
execute'ls-l'\n");
if(execlp("ls","ls","-l",NULL)<0)
{
printf("Child1execlperror\n");
}
}
if(child2==-1)/*子进程2的出错处理*/
{
printf("Child2forkerror\n");
exit
(1);
}
elseif(child2==0)/*在子进程2中使其暂停5s*/
{
printf("Inchild2:
sleepfor5secondsandthenexit\n");
sleep(5);
exit(0);
}
else/*在父进程中等待两个子进程的退出*/
{
printf("Infatherprocess:
\n");
child=waitpid(child1,NULL,0);/*阻塞式等待*/
if(child==child1)
{
printf("Getchild1exitcode\n");
}
else
{
printf("Erroroccured!
\n");
}
do
{
child=waitpid(child2,NULL,WNOHANG);/*非阻塞式等待*/
if(child==0)
{
printf("Thechild2processhasnotexited!
\n");
sleep
(1);
}
}while(child==0);
if(child==child2)
{
printf("Getchild2exitcode\n");
}
else
{
printf("Erroroccured!
\n");
}
}
exit(0);
}
编译和运行以上代码,并观察其运行结果。
它的结果是我们所希望的吗?
答:
不是
看完前面的代码之后,再观察下面的代码,它们之间有什么区别,会解决哪些问题。
答:
将child2进程的产生放在判断不是child1进程的执行代码中,在第一个例子中
由于进程1在执行的时候又fork出一个进程,导致产生了第四个进程,这个进程是child1的子进程,它会将ls命令在执行一遍,而在第二个例子中由于产生child代码放在
判断中,故而可以避免在child1中重复fork新进程。
/*multi_proc.c*/
#include
#include
#include
#include
#include
intmain(void)
{
pid_tchild1,child2,child;
/*创建两个子进程*/
child1=fork();
/*子进程1的出错处理*/
if(child1==-1)
{
printf("Child1forkerror\n");
exit
(1);
}
elseif(child1==0)/*在子进程1中调用execlp()函数*/
{
printf("Inchild1:
execute'ls-l'\n");
if(execlp("ls","ls","-l",NULL)<0)
{
printf("Child1execlperror\n");
}
}
else/*在父进程中再创建进程2,然后等待两个子进程的退出*/
{
child2=fork();
if(child2==-1)/*子进程2的出错处理*/
{
printf("Child2forkerror\n");
exit
(1);
}
elseif(child2==0)/*在子进程2中使其暂停5s*/
{
printf("Inchild2:
sleepfor5secondsandthenexit\n");
sleep(5);
exit(0);
}
printf("Infatherprocess:
\n");
child=waitpid(child1,NULL,0);/*阻塞式等待*/
if(child==child1)
{
printf("Getchild1exitcode\n");
}
else
{
printf("Erroroccured!
\n");
}
do
{
child=waitpid(child2,NULL,WNOHANG);/*非阻塞式等待*/
if(child==0)
{
printf("Thechild2processhasnotexited!
\n");
sleep
(1);
}
}while(child==0);
if(child==child2)
{
printf("Getchild2exitcode\n");
}
else
{
printf("Erroroccured!
\n");
}
}
exit(0);
}
(3)编译并运行程序
例子1运行结果:
Infatherprocess:
Inchild2:
sleepfor5secondsandthenexit
Inchild1:
execute'ls-l'
Inchild1:
execute'ls-l'
总用量12
-rwxrwxr-x.1chengchangfuchengchangfu75305月2316:
01muti_proc
-rw-rw-r--.1chengchangfuchengchangfu17565月2315:
59muti_proc.c
总用量12
-rwxrwxr-x.1chengchangfuchengchangfu75305月2316:
01muti_proc
-rw-rw-r--.1chengchangfuchengchangfu17565月2315:
59muti_proc.c
Getchild1exitcode
Thechild2processhasnotexited!
Thechild2processhasnotexited!
Thechild2processhasnotexited!
Thechild2processhasnotexited!
Thechild2processhasnotexited!
Getchild2exitcode
例子2运行结果:
Infatherprocess:
Inchild2:
sleepfor5secondsandthenexit
Inchild1:
execute'ls-l'
总用量28
-rwxrwxr-x.1chengchangfuchengchangfu75305月2316:
01muti_proc
-rwxrwxr-x.1chengchangfuchengchangfu75315月2316:
12muti_proc2
-rw-rw-r--.1chengchangfuchengchangfu18455月2316:
11muti_proc2.c
-rw-rw-r--.1chengchangfuchengchangfu18435月2316:
10muti_proc2.c~
-rw-rw-r--.1chengchangfuchengchangfu17565月2315:
59muti_proc.c
Getchild1exitcode
Thechild2processhasnotexited!
Thechild2processhasnotexited!
Thechild2processhasnotexited!
Thechild2processhasnotexited!
Thechild2processhasnotexited!
Getchild2exitcode
4.完成实验报告
实验总结:
答:
整个fork函数可以这样理解:
它复制当前进程内所有的状态,并在其复制处的代码开始执行子进程,在例子中child1产生的时候child2还没有产生,故而在它的进程里又重复fork了child2,从而造成错误。
5.思考问题
在目标板上运行的结果如下所示(具体内容与各自的系统有关):
因为几个子进程的执行有竞争关系,因此,结果中的顺序是随机的。
读者可以思考,怎样才可以保证子进程的执行顺序呢?
答:
使用信号同步,wait()与signal()
2编写守护进程
1.实验目的
通过编写一个完整的守护进程,使读者掌握守护进程编写和调试的方法,并且进一步熟悉如何编写多进程程序。
2.实验内容
在该实验中,读者首先建立起一个守护进程,然后在该守护进程中新建一个子进程,该子进程暂停10s,然后自动退出,并由守护进程收集子进程退出的消息。
在这里,子进程和守护进程的退出消息都在