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

First of all, I'm on a unix box, running apache with perl 5.6.1.

I've been banging my head for three days trying to figure this out and can't manage to. What I have is a cgi that basically asks for usernames, devices names, passwords, etc and then passes those items to other pl files that actually do a lot of ssh connections to pull data from remote routers and switches. This is somewhat time consuming and if I just try to do it straight from the script it always times out and never finishes. So I heard a rumor that I could fork some child processes, the browser would just tell the users "Ok, its processing, it'll be done soon" and be done with it, close the browser if they want or whatever because the other scripts produce no output, they actually email the results to the user after it has been processed. But I can't seem to figure out how to fork 7-8 processes at the same time. My code is similar to this:

if (defined(param('subbed'))){ $pid = fork(); if(! $pid){ exec ("./gw1.cgi userid=" . param('userid') . " gw1=" . param( +'gw1')); exec ("./gw2.pl userid=" . param('userid') . " gw2=" . param(' +gw2') . " pswd=" . param('pswd') . " enable=" . param('enable')); } } else { PrintIndex(); }

When I launch off the page in browser, input the required data in the form and hit submit it just sits at a white page waiting until the script is completely done, which 9 times out of 10 times out. When I try to run it straight off the server command line through ssh it seems to work but doesn't launch off the second exec command. I only have two exec commands right now but when all is said and done I should have 6-7 different scripts that need to be launched off.

Can someone please help me with this as I just don't know how to proceed, if forking isn't my best option, let me know another, but I'm just stuck in a rut and can't get out.

Replies are listed 'Best First'.
Re: Need assistance with forking multiple child processes
by friedo (Prior) on Jan 10, 2008 at 20:33 UTC

    First, you must remember that exec never returns. It overwrites the calling process's memory with the new process and runs it. If you need to run multiple programs in sequence, you will have to fork a new subprocess for each one. You can either do those in parallel, or wait on each subprocess in turn to finish.

    As for doing this from Apache and closing the HTTP connection, there's a little more to it. merlyn has a great column on the subject.

Re: Need assistance with forking multiple child processes
by starX (Chaplain) on Jan 10, 2008 at 21:26 UTC
    Take a look at Chapter 16 of Programming Perl. If forking off a child process is the best way to go, you can achieve this via an anonymous pipe. Sort of like this:
    if(! $pid){ open PIPE, "| .gw1.cgi userid=param('userid') gw1=param(+'gw1')" or die "Couldn't fork $!"; }
    Although that example is highly untested, so YMMV.