0

I am trying to understand the following code:

int main(int argc, char **argv)
{
   int pid1,pid2;
   if((pid1=fork())<0)
   { 
       printf("Error bla bla");exit(1);
   }
   else printf("A");
   if((pid2=fork())<0)
   {   
      printf("Error bla bla");exit(2);
   }

  if(pid1==0)printf("B\n");
  if(pid2==0)printf("C\n");
  exit(0);
  return 0;
}

the output I get looks like this :

A  
AC  
AB  
AB  
C 

If I change the first print to printf("A\n"); the output is

A  
C  
A  
B  
B  
C 

How do the processes behave in this situation ? I know that the second fork() gets executed in both the parent process and the first child process but why does the output look like this ?
Also, why does it print the last 3 letters in that specific order ?

Bogdan Molinger
  • 251
  • 1
  • 6
  • 19
  • 1
    possible duplicate of [printf anomaly after "fork()"](http://stackoverflow.com/questions/2530663/printf-anomaly-after-fork) – pilcrow Jan 14 '15 at 18:42
  • could you make this code uglier? – Iharob Al Asimi Jan 14 '15 at 18:47
  • @iharob Actually I could, but it has been specifically written like this in order to confuse the reader , which it did in my case – Bogdan Molinger Jan 14 '15 at 19:16
  • what is the purpose? just wasting time? – Iharob Al Asimi Jan 14 '15 at 19:29
  • @iharob the purpose of what ? The purpose of the question is to understand exactly how the processes interact with each other and why the result is printed in that specific order. If you mean the purpose of the oddly written code , it's to test the readers awareness. I found this example in a lecture about Operating Systems and I was wondering how exactly it works. – Bogdan Molinger Jan 14 '15 at 19:43

2 Answers2

1

First of all, I believe the result of this sequence is not well defined - it's up to the implementor of printf() and the vagaries of process scheduling.

In general, printf() accumulates characters in a buffer, and prints them when it wants to - except that generally the presence of a newline '\n' triggers immediate printing.

If the process forks with characters still in the printf() buffer, both the parent and the child process will eventually print those characters. You fork twice, resulting in 4 processes. I'll call the original process G(randparent). G creates P(arent) at the first fork. P has pid1 == 0. Next each process forks again. Let's say G creates A(unt) and P creates C(hild). A and C have pid2 == 0. C also has pid1 == 0.

All of them have either printed the original A\n, or have A in their printf buffer.

Those with pid1 == 0 then printf B\n. If there's still an A in the buffer, it comes out as AB\n Those with pid2 == 0 then print C\n

So the sequence is

G: A(\n)
P: A(\n)B\n
A: A(\n)C\n
C: A(\n)B\nC\n

The order in which G,P,A, and C run is indeterminate. But the output of any given process appears in the order it's printf()d. It may be interlaced with output from other processes.

If A is printed with \n, then remove A(\n) from all the sequences except the grandparent.

Arlie Stephens
  • 1,146
  • 6
  • 20
  • Stepens Thank you for the response, it makes sense now. I have only one question left, why does one process only print `C` ? Is it because the buffer decides to empty itself, or is there some other reason ? – Bogdan Molinger Jan 14 '15 at 19:39
  • I suspect what you are seeing is process C. In the first variant, it will print AB on one line, then C on another line. – Arlie Stephens Jan 14 '15 at 21:43
0

Probable cause of your confusion is that the output of printf("A"); is not actually written on the terminal at the moment of the second fork. It is in a memory buffer and as such it is duplicated together with the rest of the process.

Marian
  • 7,402
  • 2
  • 22
  • 34