0

I try to draw out the process according to the code but I really need some explanation in why, here is the question:

B() {
     pid_t pid;
     if ((pid = fork()) != 0)
         waitpid(pid,NULL,0);
     printf("2");
     if(fork() ==0)
       { printf("3"); exit(0); }
     printf("5");
     exit(0);
}

Which one are illegals output?
232553, 235325, 232355, 235253, 252533...

This is the process I draw out according to the code and my understanding of fork.

            ___3 (exit so no more here)
           |
      __2__|___5 (I guess 5 should be here)
     |          |        
     |          |
 ____|____(wait)|(start again since printf 3 process end)

So I'm stuck right there... Any help is appreciated.

Rozen
  • 139
  • 1
  • 2
  • 14
  • You shouldn't expect to see the output in any particular order ... besides "2" being first – paulsm4 Nov 25 '13 at 07:54
  • That is true, what I mean though, is how the rest play out? The drawing is my interpretation of the code and it is not finish. What I want to ask though, is that what else would appear after wait? – Rozen Nov 25 '13 at 08:01

5 Answers5

3

Okay, there are two forks. Here is control flow, from left to right, with parents on top and children on the bottom:

    +-- B ---- waitpid() --+                  +-- "5" -- E
    |                      |                  |
A --+ fork()               +-- C -- "2" -- D -+ fork()
    |                      |                  |
    +----------------------+                  +-- "3" -- F

So, what do we know?

  • "2", "5", and "3" each appear twice (90 possibilities)

  • No prefix may contain more "3" than "2" (30 possibilities)

  • No prefix may contain more "5" than "2" (16 possibilities)

  • The second "2" must be preceded by the first "5" (7 possibilities)

The 7 possibilities are:

2,3,5,2,3,5
2,3,5,2,5,3
2,5,2,3,3,5
2,5,2,3,5,3
2,5,2,5,3,3
2,5,3,2,3,5
2,5,3,2,5,3
Dietrich Epp
  • 205,541
  • 37
  • 345
  • 415
2

This should be the program path (x denotes termination):

---+--(wait)-2-+-5-x
   |           |
   +-2-+-5-x   +-3-x
       |   
       +-*3-x

After the first fork, the parent waits for the child to finish. But in case of second fork, it does not wait. So, * marked 3 can be printed anywhere after first 2. The order of printing 5 and 3 after second fork also can not be determined. Therefore, the possible outputs are:

25235*3
25253*3
2523*35
2525*33
252*335
252*353
25*3235
25*3253
2*35235
2*35253

asif
  • 975
  • 8
  • 16
1

Since the order of execution with fork() is not deterministic, you can only expect that each integer (i.e., 2, 3 and 5) will be printed twice. The order depends on how the scheduler chooses to schedule the processes.

You can force a particular order using sleep commands or some other synchronization primitive.

Claudio
  • 10,614
  • 4
  • 31
  • 71
1

The first fork() splits the process into 2 parts (parent and child). The parent waits and the child prints 2.

Then the child does fork(); and then child prints 5 and exits (which allows the parent to start running again) while the child's child (grandchild?) prints 3. This can happen in any order.

The parent continues and prints 2 (this may happen before or after the grandchild prints 3; but after the now terminated child printed 5).

Then the parent does fork(); and the parent prints 5 and it's second child prints 2 (which can happen in any order, and may happen before the grandchild prints 5).

Brendan
  • 35,656
  • 2
  • 39
  • 66
0

The first fork creates a child and waits for it. So the main program only goes on running as soon as the first child exits.

So the first output is "the child's" 2. Then a 3 and a 5 is printed, in any order. Only after the 3 or the 5 the second 2 can occur, and then the second 3 and/or 5.

So

232553 is ok
235325 is not ok, as the 2nd 3 comes before the 2nd 2
232355 is ok
235253 is ok
252533 is ok
glglgl
  • 89,107
  • 13
  • 149
  • 217