David Brown
David Brown

Reputation: 1

Use Fork() to create three child processes with only 2 grandchild processes

Using fork() to create child process, I am trying to make a tree that looks like this:

    p
  / | \
 p  p  p
   / \
  p   p

I have the parent create the three children processes, but I can't get the two outside children to stop forking and the second child to only fork twice.

Here is my code:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

int main ()
 {

pid_t lchildpid, rchildpid,mchildpid, parentpid;
int n = 0;
lchildpid = 0;
rchildpid = 0;
mchildpid = 0;


 printf("\nLvl\tProc\tParent\tChild 1\tChild 2\tChild 3\n");
printf("No.\tID\tID\tID\tID\tID\n");

 while(n < 3){


if((lchildpid = fork()) == 0 || (mchildpid = fork()) == 0 || (rchildpid = fork()) == 0) {

        parentpid = getppid();
        n++;
        continue;

    }

    //check for forking errors
    if(lchildpid == -1 || rchildpid == -1 || mchildpid == -1) 
    {
        perror("\n The fork failed\n");
        exit(1);
    }

    //If current fork has two children, print complete generation to console and exit while loop
    if(lchildpid && rchildpid && mchildpid ){
        printf("%d\t%ld\t%ld\t%ld\t%ld\t%ld\n",n, (long)getpid(), (long)getppid(), (long)lchildpid, (long)mchildpid,(long)rchildpid);
        break;


      }

 }
       exit(0);
 }      

Here is my output:

   Lvl     Proc    Parent  Child 1 Child 2 Child 3                                                                                                                                   
   No.     ID      ID      ID      ID      ID                                                                                                                                        
    0       22      7       23      24      25                                                                                                                                        
    1       23      1       26      28      32                                                                                                                                        
    1       25      1       29      31      33                                                                                                                                        
    1       24      1       27      30      34                                                                                                                                

I want this output:

    Lvl     Proc    Parent  Child 1 Child 2 Child 3                                                                                                                                   
    No.     ID      ID      ID      ID      ID                                                                                                                                        
     0       40      7       41      42      43                                                                                                                                        
     1       41      40       0       0      0                                                                                                                                
     1       42      40      44      45      0                                                                                                                                        
     1       43      40       0       0      0        

Upvotes: 0

Views: 1691

Answers (1)

John Bollinger
John Bollinger

Reputation: 180181

You're dealing with the fact that fork() returns twice (on success): once in the parent process, and once in the child process. These cases can be distinguished by the return value. Since fork() does return in each child, it doesn't make much sense to assign the values to lchildpid, mchildpid, and rchildpid, because every process will have its own copies of these variables. If the forking worked as you wanted, then some of those copies would be initialized and others not.

It is possible write a single expression that produces the forking pattern you presented, by making use of the short-circuiting behavior of the && and || operators and of the fact that the return value of fork() evaluates to true in the parent (even when fork() fails) and to false in the child. If you need to do this then think about it a bit and fiddle -- you'll work it out. Hint: use parentheses as necessary, and if needed you can include an integer constant among your && and || operands to direct the result of those operations.

It's a kinda interesting problem to write a single expression that does all the forking. If you don't have to do that, however, then it might be easier to just use if or switch statements to branch to appropriate behavior for the result of each fork(). That would be more characteristic of how fork() is usually used in real programs.

I hope that helps, but if you were looking for someone to do your homework for you, then I'm afraid I'm going to have to disappoint you.

Upvotes: 1

Related Questions