父进程与子进程之间的 困惑!

jqx_ah 2008-09-09 01:22:41
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>

int main(void)
{
pid_t pid2;
pid_t pid=fork();
if(pid==0)
{
int j ;
for(j=0;j<5;j++)
{
printf("child: %d\n",j);
sleep(1);
}
}
else if (pid>0)
{
int i;
for(i=0;i<5;i++)
{
printf("parent: %d\n",i);
sleep(1);
}
}
else
{
fprintf(stderr,"can't fork ,error %d\n",errno);
exit(1);
}
pid2=fork();
if(pid2==0){printf(" pid2 \n");}
printf("This is the end !\n");
return 0;
}

-------------------------------------------------------------------
./a.out
结果是:jqx2008@jqx55ah:~$ ./a.out
child: 0
parent: 0
child: 1
parent: 1
child: 2
parent: 2
child: 3
parent: 3
child: 4
parent: 4
pid2
This is the end !
pid2
This is the end !
This is the end !
jqx2008@jqx55ah:~$ This is the end !


问题是:一共会产生几个子进程?
输出结果 最后,面那5行怎么解释啊 ?
-------------------------------------------------------
同样这个题目:
./a.out > ty.txt
输出结果却是:

child: 0
child: 1
child: 2
child: 3
child: 4
pid2
This is the end !
parent: 0
parent: 1
parent: 2
parent: 3
parent: 4
pid2
This is the end !
parent: 0
parent: 1
parent: 2
parent: 3
parent: 4
This is the end !
child: 0
child: 1
child: 2
child: 3
child: 4
This is the end !

为什么将结果写进文件 就是这样一个形式了?

大家抽个时间 解释撒!
谢谢哈!
...全文
486 15 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
yangyibin 2009-05-13
  • 打赏
  • 举报
回复
我用2楼程序运行发现最后6行并不固定,以下几个情况都随机出现:
情况1
6917--6914: pid2
6917--6914: This is the end !
6918--6913: pid2
6918--6913: This is the end !
6914--6913: This is the end !
6913--4174: This is the end !
情况2
6921--6920: pid2
6921--6920: This is the end !
6922--6919: pid2
6922--6919: This is the end !
6919--4174: This is the end !
yyb@yyb-desktop:~/myprog/exec$ 6920--1: This is the end !
情况3
6931--6930: pid2
6931--6930: This is the end !
6930--6929: This is the end !
6932--6929: pid2
6932--6929: This is the end !
6929--4174: This is the end !
而其中情况2出现概率大。
zzjjlzh 2008-09-13
  • 打赏
  • 举报
回复
真是长知识啊,不错,学习了
jqx_ah 2008-09-09
  • 打赏
  • 举报
回复
谢谢哈!了解了!
jqx_ah 2008-09-09
  • 打赏
  • 举报
回复
9#的结果 很好理解ha !
可我用2#的代码运行
结果却是:
14582--14581: child: 0
14581--13075: parent: 0
14582--14581: child: 1
14581--13075: parent: 1
14582--14581: child: 2
14581--13075: parent: 2
14582--14581: child: 3
14581--13075: parent: 3
14582--14581: child: 4
14581--13075: parent: 4
14584--14582: pid2
14584--14582: This is the end !
14585--14581: pid2
14585--14581: This is the end !
14581--13075: This is the end !
jqx2008@jqx55ah:~$ 14582--1: This is the end !

难道是我的终端问题?
略略明白了一些
谢谢大家
brookmill 2008-09-09
  • 打赏
  • 举报
回复
关于6楼和7楼的问题:
fork之后,父进程和子进程执行的先后次序,本身是不确定的。如果不用wait之类的函数来人为控制,有可能父进程先执行,也可能子进程先执行。
7楼的shell提示符"jqx2008@jqx55ah:~$",是在父进程14262结束的时候打印出来的,而这时子进程14263还没结束,所以出现了6楼所说的现象;而且由于14263的父进程在它结束之前就先结束了,所以14263被系统的init进程(1号进程)给“收养”了
brookmill 2008-09-09
  • 打赏
  • 举报
回复
9楼的结果就很清楚了,确实和缓冲区有关。
貌似可以这样解释:
当运行a.out的时候,printf的结果会很快从缓冲区里输出;
而运行a.out > ty.txt的时候,printf的结果会在缓冲区里存放很长时间,可能是操作系统不太舍得频繁向硬盘里写数据。
brookmill 2008-09-09
  • 打赏
  • 举报
回复
为了验证8楼的想法,把2楼的printf后面都加上fflush:
int main(void)
{
pid_t pid2;
pid_t pid=fork();
if(pid==0)
{
int j ;
for(j=0;j <5;j++)
{
printf("%d--%d: child: %d\n",getpid(), getppid(),j);
fflush(stdout); ///////////////////////
sleep(1);
}
}
else if (pid>0)
{
int i;
for(i=0;i <5;i++)
{
printf("%d--%d: parent: %d\n",getpid(),getppid(),i);
fflush(stdout); ///////////////////////
sleep(1);
}
}
else
{
fprintf(stderr,"can't fork ,error %d\n",errno);
exit(1);
}
pid2=fork();
if(pid2==0){printf("%d--%d: pid2 \n", getpid(), getppid());}
printf("%d--%d: This is the end !\n",getpid(), getppid());
return 0;
}

这次./a.out > ty.txt 的结果:
25595--25594: child: 0
25594--25384: parent: 0
25594--25384: parent: 1
25595--25594: child: 1
25594--25384: parent: 2
25595--25594: child: 2
25594--25384: parent: 3
25595--25594: child: 3
25594--25384: parent: 4
25595--25594: child: 4
25596--25594: pid2
25596--25594: This is the end !
25594--25384: This is the end !
25597--25595: pid2
25597--25595: This is the end !
25595--1: This is the end !
brookmill 2008-09-09
  • 打赏
  • 举报
回复
从5楼的结果来看,父进程25536貌似执行了2次,但我们都知道那是不可能的。
所以恐怕只能用缓冲区来解释了:父进程25536先打印了5行parent%d在缓冲区里,然后被子进程25537复制过去,然后在25536和25537里各输出了一次?
jqx_ah 2008-09-09
  • 打赏
  • 举报
回复
我的gcc编译器运行2楼的结果是:

14263--14262: child: 0
14262--13075: parent: 0
14263--14262: child: 1
14262--13075: parent: 1
14263--14262: child: 2
14262--13075: parent: 2
14263--14262: child: 3
14262--13075: parent: 3
14263--14262: child: 4
14262--13075: parent: 4
14266--14262: pid2
14266--14262: This is the end !
14265--14263: pid2
14265--14263: This is the end !
14262--13075: This is the end !
jqx2008@jqx55ah:~$ 14263--1: This is the end !


我想最后6行应该为:
pid2
This is the end !
This is the end !
pid2
This is the end !
This is the end !
jqx2008@jqx55ah:~$


还请指教!
jqx_ah 2008-09-09
  • 打赏
  • 举报
回复
另外 最后一行的输出也挺奇怪的!
jqx2008@jqx55ah:~$ This is the end !

This is the end !在后面去了!

而且终端只有再按一下回车!
才能正常显示下面一行:
jqx2008@jqx55ah:~$
brookmill 2008-09-09
  • 打赏
  • 举报
回复
用2楼的代码,运行./a.out > ty.txt
结果:
25536--25384: parent: 0
25536--25384: parent: 1
25536--25384: parent: 2
25536--25384: parent: 3
25536--25384: parent: 4
25538--25536: pid2
25538--25536: This is the end !
25536--25384: parent: 0
25536--25384: parent: 1
25536--25384: parent: 2
25536--25384: parent: 3
25536--25384: parent: 4
25536--25384: This is the end !
25537--25536: child: 0
25537--25536: child: 1
25537--25536: child: 2
25537--25536: child: 3
25537--25536: child: 4
25539--25537: pid2
25539--25537: This is the end !
25537--25536: child: 0
25537--25536: child: 1
25537--25536: child: 2
25537--25536: child: 3
25537--25536: child: 4
25537--1: This is the end !

25384:shell
25536:父进程
25537:第一次fork产生的子进程
25538:父进程产生的子进程pid2
25539:25537产生的子进程pid2
至于为什么是这个结果,我暂时还没想出来。
jqx_ah 2008-09-09
  • 打赏
  • 举报
回复
那 那个文件输出又是什么问题?!
brookmill 2008-09-09
  • 打赏
  • 举报
回复
2楼的代码执行结果:
$ ./a.out
25520--25519: child: 0
25519--25384: parent: 0
25519--25384: parent: 1
25520--25519: child: 1
25519--25384: parent: 2
25520--25519: child: 2
25519--25384: parent: 3
25520--25519: child: 3
25519--25384: parent: 4
25520--25519: child: 4
25521--25519: pid2
25521--25519: This is the end !
25519--25384: This is the end !
$ 25522--25520: pid2
25522--25520: This is the end !
25520--1: This is the end !

25384:shell
25519:父进程
25520:第一次fork产生的子进程
25521:父进程产生的子进程pid2
25522:25520产生的子进程pid2
brookmill 2008-09-09
  • 打赏
  • 举报
回复
1楼说错了。
第一个fork执行了1次,
pid2=fork(); 这个由父进程和第一个fork产生的第一个子进程各执行了一次
所以一共产生了3个子进程。
"This is the end ! "和缓冲区没关系,它被父进程和3个子进程各执行了一次。
把所有的printf都加上pid和ppid应该就能看清楚了:
int main(void)
{
pid_t pid2;
pid_t pid=fork();
if(pid==0)
{
int j ;
for(j=0;j <5;j++)
{
printf("%d--%d: child: %d\n",getpid(), getppid(),j);
sleep(1);
}
}
else if (pid>0)
{
int i;
for(i=0;i <5;i++)
{
printf("%d--%d: parent: %d\n",getpid(),getppid(),i);
sleep(1);
}
}
else
{
fprintf(stderr,"can't fork ,error %d\n",errno);
exit(1);
}
pid2=fork();
if(pid2==0){printf("%d--%d: pid2 \n", getpid(), getppid());}
printf("%d--%d: This is the end !\n",getpid(), getppid());
return 0;
}

brookmill 2008-09-09
  • 打赏
  • 举报
回复
调用了2次fork,所以产生2个子进程
至于输出的问题,我也不是很明白,不过有个印象,在fork的时候,子进程复制了父进程的资源,其中包括输出缓冲区,所以"This is the end ! "可能是子进程复制过去之后由子进程输出的。

70,020

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧