I can get no http output until each of the kicked-off scripts has finished.

The important thing here is to close the standard file handles in the child processes. In particular stdout and stderr — stdin is not an issue here, as the associated pipe is for sending data from Apache to the CGI script, and when done, Apache takes care of closing this pipe itself.

Background:  when Apache runs an external program (CGI script) to generate content, it creates three pipes to that process:

--------- ----------------- | | form data | | | | -------------> | stdin | | | | | -----> | | HTML content | CGI | browser | Apache | <------------- | stdout script | <----- | | | | | | error msgs | | | | <------------- | stderr | | | | | --------- -----------------

The first one, which is connected to stdin of the CGI script, is used for sending form data, etc. to the script. The second one, which is connected to stdout of the script, is used for reading any content the script produces. And the last one, connected to the script's stderr, is used to read error messages, if there should be any. (This by default ends up in the webserver's error log, but may also be redirected to the browser.)

When the CGI script creates further child processes via fork or fork/exec (and system also is fork/exec under the hood), all file handles are duplicated due to the fork

--------- ----------------- | | form data | | | | -------------> | ----------------- | | -----------------> | | -----> | | HTML content | | | browser | Apache | <------------- | | | <----- | | <----------------- | child | | | error msgs | | process | | | <------------- | | | | | <----------------- | | --------- ---| | -----------------

and Apache will wait for all of them to be closed, before it stops reading from the script's stdout/stderr and consideres the dynamic content generation to be finished (Apache has to wait because it cannot tell when the script has finished generating content — which is normally indicated by the script closing the pipe).  So, unless the child processes do close the handles themselves, this won't happen before the processes terminate.

In short, with long running background processes, you have to close stdout/stderr yourself (or redirect them to a file, if they are being used).  As system provides no direct way to manipulate the duplicated file handles, it's usually easiest to explicitly fork/exec, which gives you more control:

my $pid = fork; die "fork failed: $!" unless defined($pid); if ( $pid == 0 ) { # child close STDOUT; # <--- !! close STDERR; # <--- !! ... exec $program, @args; die "exec failed"; }

Another thing to consider is that the background processes typically won't automatically terminate when the alarm fires. So if you want them to terminate, just kill them yourself (which is easy, as you have their PIDs).  And in case the background processes do (or may) fork further childrem, it's usually best to create a separate process group for them (setpgrp), and then kill the entire group by sending a negative signal number to the ID of the process group.

Also, in case you should be running in a persistent environment (FCGI, mod_perl), don't forget to wait/waitpid for the terminated child processes, or else zombies will accumulate. (For a regular CGI script, this is not an issue, because as soon as the respective parent (the main CGI script) terminates, any of its zombies will be taken care of by the OS.)


In reply to Re: Perl / Apache 2 / Alarms by Eliya
in thread Perl / Apache 2 / Alarms by DanielSpaniel

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.