LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1053|回复: 4

看一下fork两次的问题

[复制链接]
发表于 2006-3-1 13:17:41 | 显示全部楼层 |阅读模式
#include <unistd.h>
#include <stdio.h>
#include <errno.h>


int main(void)
{
        pid_t pid;
        if ( (pid = fork() )<0 )
        {
                perror("fork error");
                exit (1);
        }
        else
                if ( pid ==0 )           
                {
                        if (  (pid=fork() )<0 )
                        {
                                perror("fork error");
                                exit (2);                       
                        }
                        else
                                if (pid>0)      /
                                        exit (0);
                       
                        sleep (2);         //
                        printf("second child ,parent pid =%d\n",getppid() );
                        exit (0);      
                       
               
               
                }
       
        if ( waitpid (pid, NULL, 0 )!=pid )   
                {
                        perror ("waitpid error");
                        exit (3);
                }
        exit (0);
       
}
    是AUPE上的P152的源码,对此程序,我分析如下:

首先父进程fork了一个儿子进程,此时父进程与儿子进程同时运行,在儿子进程中有一些语句,暂不管它。此时肯定是父进程先执行到waitpid 这一句,此时,pid为儿子进程的pid,等待儿子进程结束。
   现在分析儿子进程,在儿子进程中, fork了一个孙子进程,此时儿子进程和孙子进程同时运行, 此时的pid变量如果等于孙子进程的id时,就执行if (pid>0) exit(0);可见孙子进程立即退出 ,pid变量如果不等于孙子进程pid ,则必为0,(不考虑fork失败的情况),可见
        sleep (2);         //
        printf("second child ,parent pid =%d\n",getppid() );
        exit (0);                                  
这几句是由儿子进程运行的, sleep,printf之后,儿子进程也exit了。

而书中  却说  在孙子进程中调用sleep以保证在打印父进程ID时儿子进程已终止。   不解,与我理解的大相竟庭。

请高手给我耐心的给我解释一下,不胜感激。
发表于 2006-3-1 13:34:10 | 显示全部楼层
先用code或php标签把代码格式调好
回复 支持 反对

使用道具 举报

发表于 2006-3-1 17:29:39 | 显示全部楼层
Post by todaygood
此时肯定是父进程先执行到waitpid 这一句,...

APUE, 或者 fork(2) 的手册也多次说到, fork 以后父子进程的执行顺序不定.

就执行if (pid>0) exit(0);可见孙子进程立即退出

孙子进程, 或者如程序中所说的第二个子进程怎么会立即退出呢?
if(pid > 0) exit(0); 是说如果第一个子进行执行的 fork 成功, 第一个子进程就立即退出.
fork 成功后会在父进程中返回其生成的子进程的 pid, 该值一定大于 0; 而在子进程中返回
的则是 0.

sleep (2);         //
        printf("second child ,parent pid =%d\n",getppid() );
        exit (0);                                  
这几句是由儿子进程运行的,

恰好这几句是由第二个子进程执行的. 原因见上.

在孙子进程中调用sleep以保证在打印父进程ID时儿子进程已终止。

这种方法不可靠, 其结果和当时系统的负载已经调度算法都有关系, APUE 中也提到了这一点.

不解,与我理解的大相竟庭。

与你的理解大相径庭是因为你理解错了, 或者没有认真看书 :-)

这个例子是在讲解如果进程的父进程在其退出前就已退出, 该子进程会被"过继"给 init 进程时
出现的, 建议还是再仔细的看一下APUE中的相关讲解.
回复 支持 反对

使用道具 举报

发表于 2006-3-2 10:15:38 | 显示全部楼层
楼主,上面的兄弟说的对
你搞错fork函数了
如果是父进程返回的pid是子进程所以>0
如果是子进程返回的pid=0所以pid>0是说明如果这个条件是父进程则执行下面的内容
pid==0 则说明这个条件是对子进程有用
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-3-2 20:06:12 | 显示全部楼层
MMMIX, 多谢赐教!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表