#include #include #include #include #include /* function prototypes */ int child(); void parent( int children ); int main() { int i, children = 8; /* based on a true story .... */ for ( i = 0 ; i < children ; i++ ) { /* fork a child process */ pid_t z = fork(); if ( z < 0 ) { fprintf( stderr, "ERROR: fork() failed.\n" ); exit( 1 ); } if ( z == 0 ) { int rc = child(); exit( rc ); } } parent( children ); return 0; } int child() { int t; printf( "CHILD: I'm new. My pid is %d.\n", getpid() ); srand( getpid() * getpid() ); t = 10 + ( rand() % 21 ); /* in range [10,30] */ printf( "CHILD: I'm gonna nap for %d seconds.\n", t ); sleep( t ); return t; } void parent( int children ) { int status; /* return status from a child process */ pid_t child_pid; printf( "PARENT: I'm waiting for my children.\n" ); while ( children > 0 ) { #if 0 /* wait (BLOCK!) until child process exits */ child_pid = wait( &status ); #endif /* see if a child has terminated -- NONBLOCKING wait */ child_pid = waitpid( 0, &status, WNOHANG ); if ( child_pid == 0 ) { printf( "PARENT: I'm still waiting. I'll take nap.\n" ); sleep( 3 ); } else { /* one less child to wait for ... */ children--; printf( "PARENT: child process id %d exited", child_pid ); if ( ( status & 0x000F ) != 0 ) { printf( " abnormally.\n" ); } else { int rc = status >> 8; /* shift right 8 bits */ rc = rc & 0x00FF; /* mask most-significant bytes */ printf( " after sleeping for %d seconds.\n", rc ); } printf( "PARENT: %d more to go.\n", children ); } } printf( "PARENT: All done.\n" ); }