chacal has asked for the wisdom of the Perl Monks concerning the following question:

Hello, I'm trying to write a very simple stress tester in perl, to make sure mysql is set to handle 100's of connections correctly. I tried to write a script that forks off a few hundred jobs that each use LWP to do a 'get' on a webpage. I just tried to hack the example i could find about forking, but i'm pertty unclear about how it works. Below is the code:
#!/usr/bin/perl use LWP::Simple qw(get); sub getweb { for ($i=0;$i<200;$i++) { if(!defined($pid = fork)) { return; } if($pid) { #parent $SIG{CHLD} = sub { wait; }; return; } else { get("http://www.blahblah.com/blah.php3?xxx"); return; } } } getweb;
Thanks, Phil

Replies are listed 'Best First'.
Re: how to fork?
by turnstep (Parson) on Apr 06, 2000 at 19:02 UTC

    If you are checking whether pid is defined, you should do more with it, otherwise you can just say if ($pid=fork)

    A fork command can return three possible values:

    1. A positive integer, representing the PID (process ID), in other words, the name of the child. This means that the fork was successful, and you are the parent.
    2. A zero. This means the fork was successful, and you are the child. You can get the name of your parent with the getppid command.
    3. Undefined, which means that the fork failed, and therefore, you are the "parent" (who may have other children, but this attempt failed). When this happens, you can look to see what is in the $! variable to try and figure out what went wrong. Usually, it's because A) You can't fork (e.g. an MS-DOS shell) or B) you have no more processes available. This is a bad thing. Not fatal, but bad. You could sleep and try again (see page 167 of Programming Perl) but best to just 'die' and figure out what's going on.

    To further the previous poster's comment, you can not only get rid of the return, but the whole sub as well:

    #!/usr/bin/perl $loops = shift || 200; use LWP::Simple qw(get); print "Testing with $loops children...\n"; for ($i=0;$i<$loops;$i++) { if ($pid = fork) { next; } ## Parent gets the credit... if (defined $pid) { ## ...children do the work get("http://www.blahblah.com/blah.php3?xxx"); exit; } else { ## Uh-oh something is really wrong ## The parent is saying this... die "Fork failed at number $i: $!\n"; } }
Re: how to fork?
by jbert (Priest) on Apr 06, 2000 at 20:20 UTC
    For bonus style points, build a Threading perl and abstract all this even more:

    #!perl -w use Thread; use strict; my $count = 200; foreach my $i (1..$count) { my $t = new Thread( &getit ); $t->detach(); } sub getit { # do the fetch thang }
Re: how to fork?
by chromatic (Archbishop) on Apr 06, 2000 at 18:36 UTC
    First, you'll want to get rid of the return after you set up your SIGCHLD handler. You want to fork off more than one child, right? You're leaving the loop after the first iteration this way.

    Change that, and everything else looks pretty good. The only other thing I'd do differently is call exit right after the get. That way, the child goes away after it grabs the page.

Re: how to fork?
by Fastolfe (Vicar) on Nov 08, 2001 at 00:21 UTC