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

I've got a webpage that sends data to a cgi script. This cgi script posts some of that data to another program that takes a long time to run. I want a webpage to come up saying 'your results will be emailed to you' as soon as the user presses the submit button on the webpage, rather than waiting for the slow program to finish. I thought fork would do it but I've never used it before and I can't get it to work.

A sample of my code is:

if (($FORM{'email'} =~ /\w+\@\w+/)&&($FORM{'sequence'} ne "")){ my $sequence=$FORM{'sequence'}; my $window=$FORM{'window_size'}; my $email=$FORM{'email'}; my $pid = fork(); if($pid==0){ #child process - want this to carry on in background #call subroutine that posts this info to slow-running program &get_disorder($sequence, $window, $email); } else{ #parent process - want to give use back a webpage NOW print "Your results will be emailed to you."; } }
This has no effect at all - it's still waiting for the slow-running program to before displaying 'your results will be emailed to you'. What am I doing wrong?

I also keep seeing things about zombie children but I'm not clear how to prevent them.
Thanks!

Replies are listed 'Best First'.
•Re: forking in a cgi script
by merlyn (Sage) on Mar 25, 2004 at 15:18 UTC
    The trick is to have the child close(STDOUT) after the fork. This lets the webserver see an EOF on the input handle when the parent exits, freeing the transaction with the browser.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

      I tried it, but no luck. I suddenly thought that it might be something to do with running the webpage on Apache. I found something called Apache::SubProcess but can't find any help on using it. Any ideas if this would work?
Re: forking in a cgi script
by tommycahir (Acolyte) on Mar 25, 2004 at 15:44 UTC
    i think this should get rid of your zombies for you
    use POSIX ":sys_wait_h"; sub zombie_reaper { while ( waitpid( -1, WNOHANG ) > 0 ) { } $SIG{CHLD} = \&zombie_reaper; } $SIG{CHLD} = \&zombie_reaper;
      Or even:
      # Automatically reap zombies $SIG{CHLD} = 'IGNORE';
      Marcel
Re: forking in a cgi script
by calin (Deacon) on Mar 25, 2004 at 18:29 UTC

    Here's an interesting article dealing with the issues of forking in a mod_perl environment. Most of the techniques discussed are valid for "normal" CGI programs, too.

Re: forking in a cgi script
by ccn (Vicar) on Mar 27, 2004 at 10:41 UTC
    You should not use fork for this task at all. Just print the message, close STDOUT, STDIN, then call get_disorder.