-1
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>

int main(int argc, const char * argv[]) {
    for(int i = 0; i < 2; i++){
        if(fork() == 0){
            fork();
            printf("c"); 
        }
       else{
           fork();
           printf("p"); 
       }
    }
}

I want to count how many times p and c will be printed respectively, here is my work.

Draw a process tree for i == 0:

     P
    / \
  C1   P
 / \  / \
C2 C1 C3 P

I call this a subtree. In one subtree, P gives p, C3 gives c, C1 gives p, C2 gives c. In the second iteration, each leaf will hold a subtree like this, so in the end we will have 5 subtree in total. Since one subtree gives 2 p, 2 c, 5 subtrees will gives 10 p, 10 c. But this is wrong.

What went wrong?

Update: I found I made a mistake, here is the correction: P gives p, C3 gives p, C1 gives c, C2 gives c.

keanehui
  • 185
  • 2
  • 13
  • *But this is wrong* - wrong how? – Eugene Sh. Oct 01 '20 at 15:43
  • Anyway, you might be getting some misleading results due to the duplication of the output buffers. – Eugene Sh. Oct 01 '20 at 15:54
  • @EugeneSh.Sorry that I made a mistake and it was updated shown above. Anyway, according to my idea, I eventually got 10 p and 10 c at the end, but according to the result I got from running the programme on online compiler, 16 p and 16 c would be the correct answer. And I don't understand how come we got that many of output – keanehui Oct 01 '20 at 16:02
  • As I said, when one process is printing some output, it is not necessarily goes right to the console, it might get buffered in the output buffer which *belongs to the same process*. And this buffer is duplicated when a process is forked. So both processes will print it in the end. See https://stackoverflow.com/questions/2530663/printf-anomaly-after-fork for details and possible solutions – Eugene Sh. Oct 01 '20 at 16:11
  • The code shown will only print some combination of `c` and `p` and never any `a` or `b`. – Jonathan Leffler Oct 01 '20 at 16:21

1 Answers1

0

At the first iteration, C2 C1 will each give 'c', C3 P will each give 'p'. When comes to the second iteration and start calling fork(), parent's print buffer will be copied for children.

For example, as a result of the second iteration, we have 5 "subtrees". Considering the subtree with root C2(depth = 2), from the buffer, we will have c c c c for the leaves respectively. And similarly, from fork(), we will have c c p p for the leaves respectively. So actually, each leaf of this subtree will give cc cc cp cp respectively.

Repeat this process in a similar manner, we will eventually get 16 'c' and 16 'p'.

keanehui
  • 185
  • 2
  • 13