fork() - program output?

fork() - program output?

Post by sandee » Sat, 24 May 2003 22:06:37



Hi ,

Here is my simple program:
-----------------------------
#include<stdio.h>
   main()
     {
       int i=0;

       fork();
       printf("%d",i++);
       fork();
       wait();
     }
-----------------------------

I was expecting the output of this program to be 00( i.e. 2 zeros).
But actual ouput on running this program is 0000(i.e. 4 zeros).[ I ran this
on Linux 7.0 s/m with gcc compiler].
Can some one explain why this is  so? step by step explaination will be very
helpful.

Thanks in advance,
Sandeep

 
 
 

fork() - program output?

Post by Wartan Hachaturo » Sun, 25 May 2003 02:29:23



>        fork();
>        printf("%d",i++);
>        fork();
>        wait();
> I was expecting the output of this program to be 00( i.e. 2 zeros).
> But actual ouput on running this program is 0000(i.e. 4 zeros).[ I ran this

stdout is buffered, and you don't flush it with "\n" in printf, so it
gets flushed one the exit, and "0" appears on the screen at that time.
Since with two forks you spawn four identical copies of the program,
(and each copy gets the same, unflushed stdout buffer in second fork)
you see 4 zeros at the end of each copy.
Try replacing "%d" with "%d\n", and you'll see two zeros.

[I must note that there is a special newsgroup, comp.unix.programming,
for that kind of questions].

--
Regards, Wartan.
"Computers are not intelligent. They only think they are."

 
 
 

fork() - program output?

Post by Chaitanya Atreya P. » Sun, 25 May 2003 03:04:21



>Hi ,

>Here is my simple program:
>-----------------------------
>#include<stdio.h>
>   main()
>     {
>       int i=0;

>       fork();

A child process is created here. So there are 2 processes running now.
The variable 'i' is copied from parent to child (as the child gets a
copy of parent's
stack space as part of fork call).

Quote:>       printf("%d",i++);

Each process is supposed to print the value of i (= 0) onto the standard
output.
But it defers this as the buffer is not yet flushed. (Note here that
standard I/O
library is buffered, where as *write* API is not buffered.)
So there are 2 "0"s outstanding in the standard output buffer waiting to be
flushed.

Quote:>       fork();

Now both the processes (the parent and the child process) calls fork each.
So there are 4 processes at this point. (Note, however, that the order of
creation of the child processes is undefined here).

In the process of creating 2 child processes, the parent's data space is
copied
to the their respective child processes. If you remember, there were 2
processes
before this each with a "0" in its standard output buffer. So this
buffer is also
copied as such to the child processes as mentioned earlier.

There are 4 "0"s in the standard output buffer altogether at this point
(i.e., when
all the four processes reach this point). They are not yet in the standard
output.

Quote:>       wait();

Before the program ends, the operating system flushes all the open
buffers on behalf
of the terminating processes. So the 4 outstanding "0" from 4 processes
are flushed
to the standard output. Now the output is "0000".

Hope that was clear.
To, however, get the output as just "00", change the printf as:
printf("%d\n", i++);
It works.........
I think you can realise what happens with the "\n" after the explanation
that went above!!

or use the following line instead of printf:
write(1 /* stdout */, "0", 1);

Quote:>     }
>-----------------------------

>I was expecting the output of this program to be 00( i.e. 2 zeros).
>But actual ouput on running this program is 0000(i.e. 4 zeros).[ I ran this
>on Linux 7.0 s/m with gcc compiler].
>Can some one explain why this is  so? step by step explaination will be very
>helpful.

>Thanks in advance,
>Sandeep

Bye,
./Chaitanya Atreya
 
 
 

fork() - program output?

Post by Wartan Hachaturo » Sun, 25 May 2003 02:51:18



> [I must note that there is a special newsgroup, comp.unix.programming,
> for that kind of questions].

comp.unix.programmer, sorry.

--
Regards, Wartan.
"Computers are not intelligent. They only think they are."

 
 
 

fork() - program output?

Post by Paul Pluzhniko » Sun, 25 May 2003 13:03:06



Quote:> To, however, get the output as just "00", change the printf as:
> printf("%d\n", i++);
> It works.........

This works, but only when output goes to a terminal.

If you redirect output to a file, you'll get the wrong number of
zeros again. A better solution is to explicitly call fflush().

Cheers,
--
In order to understand recursion you must first understand recursion.

 
 
 

fork() - program output?

Post by sandee » Tue, 27 May 2003 16:31:38


Hi All,

Thanks to all for sharing your thougths.

Sandeep



> > To, however, get the output as just "00", change the printf as:
> > printf("%d\n", i++);
> > It works.........

> This works, but only when output goes to a terminal.

> If you redirect output to a file, you'll get the wrong number of
> zeros again. A better solution is to explicitly call fflush().

> Cheers,
> --
> In order to understand recursion you must first understand recursion.

 
 
 

fork() - program output?

Post by Pau » Sat, 31 May 2003 02:27:57


I have another question that arises out of the original problem.
Someone before mentioned that when fork is called, the standard output
buffer is also copied to the created process.  Does this mean each
process has an internal buffer used for standard input/ouput and when
the process finishes it writes this buffer to the system's standard
input/output buffer?  I am confused and new to unix, so its a bad
combination.  ;)
 
 
 

fork() - program output?

Post by Paul Pluzhniko » Sat, 31 May 2003 13:03:10



> Someone before mentioned that when fork is called, the standard output
> buffer is also copied to the created process.  Does this mean each
> process has an internal buffer used for standard input/ouput and when
> the process finishes it writes this buffer

Correct so far. That *is* what happens, IF the program uses libc
STDIO facilities, and does not reset default buffering (with setbuf,
setbuffer, etc.).

On exit(3), STDIO will write(2) whatever is left in the buffer to
the corresponding file descriptor. The kernel will then make
this data appear on a terminal or in a file (almost) immediately.

[Note that this will not happen if the program calls _exit(2)].

Quote:> to the system's standard input/output buffer?  

There exists no such thing.

Quote:> I am confused and new to unix, so its a bad combination.  ;)

A very good description of all of this can be found in a classic
text:

    Advanced Programming in the UNIX(R) Environment
    by W. Richard Stevens

    http://www.amazon.com/exec/obidos/tg/detail/-/0201563177

The book is a bit pricey, but *well* worth it.

Cheers,
--
In order to understand recursion you must first understand recursion.

 
 
 

1. Programs that fork() don't redirect output in desired way?

The following is the same on AT&T UNIX V.3 and V.4.

The scenario is that a program (a background communication interface) is
invoked, and it fork()s 2 children. The parent monitors both children, and
one child deals with inbound traffic, the other with outbound traffic.

In this program, we have a lot of printf()s used for debugging and tracing, and
are only active when we compile with a -DDEBUG compiler flag.

We let the program run in the background, and redirect stdout, and stderr to a
holding debug file, via the shell command:

prog > debug.out 2>&1

Because "prog" breaks itself into three running processes, we have three
different processes redirecting their output to the debug file.

The problem is that the file does not contain things in chronological order.
What happens is that it will contain output from the parent, then output from
child1, then output from child2, all interspersed.

I assume this is because of system buffering for printf()s.

Of course I can rewrite the printf()s so as they would write to a special log
file, but this would be a considerable effort, plus it will deprive us of the
flexibility of displaying output directly to the terminal when we want to.

What is an easy way to get the output of all three processes correctly in
correct chronological order?

Thanks in advance.
--
Khalid M. Bahey-elDin       | Voice: +966-2-651-2727 | Fax: +966-2-651-8804


P.O.Box 13964, Jeddah 21414 | UUCP:  ..!uunet!ncrlnk!ncrsaud!kbahey

2. AIX Oracle to Linux

3. Forking two programs and piping their output/input together

4. [Fwd: how to temporarily interrupt a running program]

5. comsat forking, forking and forking (3.2.0)

6. AMD SCSI support?

7. directing output of programs that are arguments of other programs

8. VisionFS manuals & setup info

9. program for read output of another program

10. Howto capture output from external program run from C program

11. forking and socket output buffers

12. Output lost in my window after pipe and fork

13. redirecting output for fork & curses Q's