newprint
newprint

Reputation: 7136

Variable values in Fork() child

I have already asked one question about fork(), here is another. Given the following code:

#include <unistd.h>
#include <stdio.h>

int main()
{
    pid_t pid1, pid2;
    pid1 = fork();
    pid2 = fork();
    if (pid1 != 0 && pid2 != 0)
        printf("A\n");
    if (pid1 != 0 || pid2 != 0)
        printf("B\n");
    exit(0);
}

After the second fork(), what would be the values of pid1 & pid2 ?
As far as understood, first fork sets the pid1 > 0 and would be identical in all children created later on. However, what would happen to pid2 ??

Thanks !

Upvotes: 4

Views: 2389

Answers (5)

paxdiablo
paxdiablo

Reputation: 881653

All you have to do is try it:

#include <unistd.h>
#include <stdio.h>
int main (void) {
    pid_t pid1 = -1, pid2 = -1;
    pid1 = fork();
    pid2 = fork();
    printf ("%5d/%5d: %5d %5d\n", getpid(), getppid(), pid1, pid2);
    sleep (5); // to prevent inheritance by init process on parent death
    return 0;
}

and you'll see:

  PID/ PPID   pid1  pid2
 ----------   ----  ----
 2507/ 2386:  2508  2509      first process
 2508/ 2507:     0  2510      first fork from 'first process'
 2509/ 2507:  2508     0      second fork from 'first process'
 2510/ 2508:     0     0      second fork from "first fork from 'first process'"

In other words:

  • the first process 2507 has pid1 and pid2 set to its two children.
  • the second process 2508 has pid1 of 0 since it was the child in that fork but pid2 of 2510 because it was the parent in that fork.
  • the third process 2509 inherits pid1 from the first process (its parent) since it forks after that's been set. Its pid2 is 0 because it's the child in the second fork.
  • the fourth process 2510 inherits pid1 from the second process (its parent) since it forks after that's been set. Its pid2 is also 0 because it's the child in the second fork.

Upvotes: 5

Robert
Robert

Reputation: 6540

I'm about to test that for you, but let me tell you what I'd expect.

                               / pid2=[child3 pid]    { pid1 = child1;pid2 = child3;}
        pid1=[child1 pid] fork()
       /                       \
      /                          pid2=0               { pid1 = child1;pid2 = 0;}
fork()
      \                          pid2=[child2 pid]    { pid1 = 0;     pid2 = child2;}
       \                       /
        pid1=0         - fork()
                               \ 
                                 pid2=0               { pid1 = 0;     pid2 = 0;}

EDIT Tested it. Code follows

#include <stdio.h>
#include <unistd.h>

int main()
{
    pid_t pid1, pid2;
    pid1 = fork();
    pid2 = fork();
    printf("PID %d: pid1=%d, pid2=%d\n",getpid() ,pid1, pid2);
    exit(0);
}

outputs:

PID 30805: pid1=30806, pid2=30807
PID 30806: pid1=0, pid2=30808
PID 30807: pid1=30806, pid2=0
PID 30808: pid1=0, pid2=0

Upvotes: 3

Nick Meyer
Nick Meyer

Reputation: 40292

After the second fork(), what would be the values of pid1 & pid2 ?

That depends on which process you're talking about. There are four processes (including the original) here, with the following relationship between them:

A (original process)
` - B (created by first fork in original process)
|   ` - C (created by second fork in B)
` - D (created by second fork in original process)

So in A, pid1 > 0 and pid2 > 0, because it created new processes on each fork.

In B, pid1 == 0 and pid2 > 0, because it was created by the first fork and created a new process in the second fork.

In C, pid1 == 0 and pid2 == 0, because it inherits the value of pid1 from its parent (B) and was created by the second fork.

In D, pid1 > 0 and pid2 == 0, because it inherits the value of pid1 from its parent (A) and was created by the second fork.

And of course, remember that these are just the initial conditions. Each process has its own copy of the values, so even though a process inherits the initial value of some variable from its parent, it can still be changed after the fork without affecting the parent's copy.

Upvotes: 2

Edward Strange
Edward Strange

Reputation: 40867

Read the man page: http://linux.die.net/man/2/fork

pid1 will thus be 0 in the child of the first process created in the first fork, something other in the main and its second child. pid2 will be 0 in the grandchild of the first process and the child created in the second fork in the main process. Something else everywhere else.

                                            /-[parent]pid1=?, pid2=?
      /-[parent]pid1=?, pid2=uninit -> fork()
fork()                                      \-[child2 of parent]pid1=?, pid2=0
     \
      \                                               /-[child1 of parent]pid1=0,pid2=?
       \[child1 of parent] pid1=0, pid2=uninit -> fork()
                                                      \-[child of child] pid1=0, pid2=0

Upvotes: 1

Dark Falcon
Dark Falcon

Reputation: 44181

Fork takes the process in its existing state and clones it, so now you have two identical copies. In the original process, fork then returns the PID of the new cloned process. In the new clone, fork returns 0.

Parent process:
pid1 = PID of child 1
pid2 = PID of child 3

Child 1
pid1 = 0
pid2 = PID of child 2

Child 2
pid1 = 0
pid2 = 0

Child 3
pid1 = PID of child 1
pid2 = 0

Upvotes: 6

Related Questions