user978859
user978859

Reputation:

fork() result after excecution

I just need to ask if my thoughts is correct at the following code:

c2=0;
c1=fork(); // fork #1

if (c1==0)
    c2=fork(); // fork #2

fork();  // fork #3

if(c2>0)
    fork(); // fork #4

here are my thoughts: the parent process will create the following child's:

Parent
--> c1 // fork #1
--> fork() // fork #3

c1
--> c2 //fork #2
--> fork() // fork #3
--> fork() // fork #4

c2
--> fork() // fork #3

is this correct?

Upvotes: 0

Views: 653

Answers (1)

paxdiablo
paxdiablo

Reputation: 881613

Okay, this is going to take some analysis. It's best to think about each process in turn:

0: c2=0;
1: c1=fork();
2: if (c1==0) c2=fork();
3: fork();
4: if(c2>0) fork();
5: whatever

And then create a table as follows, which steps through each process in turn:

Seq PID CurC1 CurC2 Line Fork? NewC1 NewC2 ChPID ChC1 ChC2 ChLine ChSeq
--- --- ----- ----- ---- ----- ----- ----- ----- ---- ---- ------ -----
  0   0     ?     ?    0  NA       ?     0
  1   0     ?     0    1  Y       >0           1    0    0      2     6
  2   0    >0     0    2  N
  3   0    >0     0    3  Y                    2   >0    0      4    10
  4   0    >0     0    4  N
  5   0    >0     0    5  NA

  6   1     0     0    2  Y             >0     3    0    0      3    12
  7   1     0    >0    3  Y                    4    0   >0      4    15
  8   1     0    >0    4  Y                    5    0   >0      5    17
  9   1     0    >0    5  NA

 10   2    >0     0    4  N
 11   2    >0     0    5  NA

 12   3     0     0    3  Y                    6    0    0      4    18
 13   3     0     0    4  N
 14   3     0     0    5  NA

 15   4     0    >0    4  Y                    7    0   >0      5    20
 16   4     0    >0    5  NA

 17   5     0    >0    5  NA

 18   6     0     0    4  N
 19   6     0    >0    5  NA

 20   7     0    >0    5  NA

In this table, the columns are:

  • Seq, the sequence number of the step.
  • PID the "process" ID executing the step.
  • CurC1 and CurC2, the values for c1/c2 before the step.
  • Line,. the line number of the step.
  • Fork?, whether a fork happens on that line.
  • NewC1 and NewC2, if the c1/c2 values are changed by the step.
  • ChPID, the process ID of the child, assuming a fork happened.
  • ChC1 and ChC2, the initial c1/c2 values of the child, assuming a fork happened.
  • ChLine, the next line in the child, assuming a fork happened.
  • ChSeq, the sequence where the child starts, assuming a fork happened.

So, from this, we can see that there are a total of eight processes that were created (including the one you ran manually at the start). That doesn't quite bear out the seven that you listed, so let's find the missing one.

The reason I'm confident that I'm correct is because running the following program (called xyzzy) in the background:

#include <unistd.h>
int main(void) {
    int c1, c2 = 0;
    c1=fork();
    if (c1==0) c2=fork();
    fork();
    if(c2>0) fork();
    sleep (60);
    return 0;
}

and then executing ps -f | grep xyzzy before any of the sleep statements finish, results in:

pax    13266 13150  0 21:01 pts/0    00:00:00 ./xyzzy
pax    13267 13266  0 21:01 pts/0    00:00:00 ./xyzzy
pax    13268 13266  0 21:01 pts/0    00:00:00 ./xyzzy
pax    13269 13267  0 21:01 pts/0    00:00:00 ./xyzzy
pax    13270 13267  0 21:01 pts/0    00:00:00 ./xyzzy
pax    13271 13267  0 21:01 pts/0    00:00:00 ./xyzzy
pax    13272 13269  0 21:01 pts/0    00:00:00 ./xyzzy
pax    13273 13270  0 21:01 pts/0    00:00:00 ./xyzzy

In other words you have, along with the mappings from your question and the PIDs in my table:

 13266 (parent)             Parent                             0
     13267                  --> c1 // fork #1                  1
         13269                  --> c2 //fork #2               3
             13272                  --> fork() // fork #3      6
         13270                  --> fork() // fork #3          4
             13273                  ???                        7
         13271                  --> fork() // fork #4          5
     13268                  --> fork() // fork #3              2

So it's PID 7 from my table. Following the sequence numbers back to the start, we end up with forks at 1, 7, 15, 20 which would be, in your original question:

The child from fork#1 then calls fork#2. The parent from that fork#2, has c2 > 0. Then, at fork#3, you end up with two processes that have c2 > 0, not one. Both of those will fork at fork#4.

Upvotes: 3

Related Questions