fork behavior

This is a discussion on fork behavior within the C Programming forums, part of the General Programming Boards category; Running the following code: Code: int run_execve ( int cid ); int so_far = 0; int MAX_PROCS = 1000; /* ...

  1. #1
    Registered User
    Join Date
    Dec 2009
    Posts
    2

    Question fork behavior

    Running the following code:
    Code:
    int run_execve ( int cid ); 
    
    int so_far = 0; 
    int MAX_PROCS = 1000;  /* create this many processes */
    
    int main(void) {
       int cid;
       
       printf ( "C\n" );
       while ( so_far < MAX_PROCS ) {
          /* attempt to run an executable */ 
          cid = fork();
          run_execve ( cid );
          printf ( "A\n" );
          so_far++;
       }
    }
    
    int run_execve ( int cid ) {
       if ( cid == 0 ) {
          exit ( -1 );
       } 
    }
    I would expect to see a single C in the output, and 1000 A's. Instead, I'm getting 72 C's and 3485 A's. This behavior makes no sense to me. Eventually, I plan to call execve from within the run_execve method, but do to the current problems, I've cut it out until I can get fork under control.

  2. #2
    Registered User
    Join Date
    Oct 2006
    Location
    Canada
    Posts
    1,243
    "fork" basically creates a copy of the current process, including copies of all of its variables, etc.. So, for example, at the start of the first iteration of the "while" loop, there is just one one copy of all of its data, such as 'cid'. In particular, each process has references to the standard streams (STDOUT, STDERR, STDIN). If they didnt, you wouldnt be able to use "printf" or "scanf", because these use the 2 default out/in streams. One important thing is that 'printf' writes to STDOUT, which is buffered. This means that the output might be unpredictable, except when you force it to print, i.e. "flush" or the stream is closed or process ends, etc.

    So your first printf statement before the while loop writes something to the buffer of STDOUT (though nothing is actually printed, yet). Next, inside the while loop you fork. You now have 2 processes, each with their own "STDOUT" buffer which (maybe or maybe not!) has the "C" in it. So when the OS eventually gets around to actually printing the stuff, theres "C\nC\n" in the buffer. This is in addition to the things that the other processes (forked children) write to this buffer. So on different runs of the program, there might even be different ordering of output, as the process scheduling isnt reliable either (unless you forced it to be, i.e. synchronized it).

    Two solutions:
    1) Write to an unbuffered stream. Basically change your "printf"s to "frprintf" to "stderr", which is unbuffered. Therefore any writes to it will happen "immediately" and reliably.
    2) "flush" "stdout" after every "printf".

    In either case you should get the expected number of characters each outputted.

  3. #3
    Registered User
    Join Date
    Dec 2009
    Posts
    2
    Thank you nadroj. Your reply fixed the problem.

    Consequently, for anyone else that finds this problem, you get different behavior using _exit versus exit depending on whether or not there is a printf statement before the exit call. Be sure to read the man page for exit carefully to understand why this is the case.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Understanding fork()
    By NuNn in forum C Programming
    Replies: 8
    Last Post: 02-27-2009, 12:09 PM
  2. Fork(), pause(), and storing PID's in a linked list
    By vital101 in forum C Programming
    Replies: 10
    Last Post: 09-28-2007, 03:16 AM
  3. Fork - unpredictable?
    By fredkwok in forum Linux Programming
    Replies: 4
    Last Post: 03-26-2006, 02:49 PM
  4. fork(), exit() - few questions!
    By s3t3c in forum C Programming
    Replies: 10
    Last Post: 11-30-2004, 06:58 AM
  5. Daemon programming: allocated memory vs. fork()
    By twisgabak in forum Linux Programming
    Replies: 2
    Last Post: 09-25-2003, 03:53 PM

Tags for this Thread


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21