http://www.perlmonks.org?node_id=990810


in reply to Help with Fork bomb

Here is a scaled down version of what you are trying to do in a fashion that will work...

#!/usr/bin/perl -w use strict; $SIG{CHLD}=\&catchChildDeath; # Track how many children we have running our $children=0; # Limits on min and max for number of children to run my $min_child=5; my $max_child=10; # Enable or disable our ability to spawn my $spawnEnabled=1; # Run until killed while(1){ spawn(); sleep 5; } exit(0); # Deal with the death of a child. A sad event to be sure. sub catchChildDeath{ printf "Death of child noted.\n"; $children--; $children = ( $children < 0 ? 0 : $children); unless ($spawnEnabled){ $spawnEnabled = ( $children < $min_child ? 1 : 0 ); } printf "There are %d children running\n",$children; } # Spawn if we must, or not. sub spawn{ unless ( $spawnEnabled ) { if ($children <= $min_child ){ $spawnEnabled=1; } else { return unless $spawnEnabled; } } if ( fork()){ $children++; $spawnEnabled = 0 if $children > $max_child; printf "%d children running\n",$children; } else { kidPlay(); } } # This encapsulates the behavior of the child. sub kidPlay{ my $iter=0; printf "Child PID: %d\n",$$; while($iter++ < 10){ sleep 1; } printf "Child PID: %d exiting..",$$; exit(0); }
Of particular note is the use of $SIG{CHLD} to catch the event of a child process exiting. Also the counters and limit values that I use to track what is going on.

When I ran this it worked marvelously. Add to it what you want. Disclaimer: this code only minimally tested and is not to be used in conjunction with ICBM launchers, nuclear reactors or transporter rooms.


Peter L. Berghold -- Unix Professional
Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg

Replies are listed 'Best First'.
Re^2: Help with Fork bomb
by Anonymous Monk on Aug 30, 2012 at 19:37 UTC

    Very interesting code. Thank you. Suppose I wanted to have the loop pass data to the child.

    my @array = (1 .. 20); foreach my $x (@array){ spawn($x); } ... sub spawn{ # the unless and : ? statements were too alien to me. my $x = shift; if ( ! $spawn_enabled ) { if ($children <= $min_child ){ $spawn_enabled=1; } elsif ( ! $spawn_enabled ) { return; } } if ( fork() ){ $children++; if ( $children > $max_child ){ $spawn_enabled = 0; } #printf "%d children running\n",$children; } else { my_child_work($x); } } sub my_child_work{ my $x = shift; print "child x $x\n"; sleep 1; exit; }

    This results is numbers being missed. In fact, I only see the numbers 1, 2 and 3 being printed when using a max of 2 children. I think this is due to my original logic flaw. I do not have the problem when using Parallel ForkManager but, I'd like to understand how to do without.

          Suppose I wanted to have the loop pass data to the child.

      Data is shared between parent/child at the time fork() happens. Once the child is running though that changes. Parent and child are then independent of one another.

      If you want a parent to communicate with the child after the fork there are a multitude of ways of doing that. Everything from duping STDIN,STDERR,STDOUT to using fifo devices to shared memory and semaphores. All depends on why you want the communication and how complicated you are willing to accomplish that goal.


      Peter L. Berghold -- Unix Professional
      Peter -at- Berghold -dot- Net; AOL IM redcowdawg Yahoo IM: blue_cowdawg