| Howdy Karjala, On 22-Apr-06, at 8:47 AM, Karjala wrote:
To chime in with another 2¢, here's a sample fork() subroutine that I've been using with great success -- completely forks from the Apache process, and dissociates from the Apache process group (so that it doesn't die if you kill Apache) and relinquishes all open handles (so it doesn't block if you try to re-start Apache and the forked process is still running). I grabbed most of the theory for this code from the URL below about how to properly fork() under mod_perl, but it was a few years ago and just fair warning -- I'm not 100% positive the way below is still "best practice". I can vouch that it works fine under Apache/*nix/mod_perl and also under CGI-Perl/Win/IIS. http://perl.apache.org/docs/1.0/guide/performance.html (see under Forking) And here's the subroutine that I use. It returns true to the child, false to the parent. You can use it something like: use MyPackage qw(ForkMe); if ( ForkMe() ) { # child here # some long process sleep (300); # all done # remember: CORE::exit() in the child otherwise might get zombie apache processes CORE::exit(); } else { # parent process here $m->print("Subprocess started."); } MyPackage ======== use POSIX (); # Running under mod_perl? BEGIN { if( exists $ENV{"MOD_PERL"} ) { use Apache; use Apache::SubProcess; } } # # call as: ForkMe() # actions: forks the current process and created a *completely indepentent* child process # (this is really useful for web application processes that need to do something that # takes a long time, and you want to fork with independance from the web server # process pool) # # returns: true to the child # false to the parent # # NOTE: specifically, if modifying code to use ForkMe(), don't forget to CORE::exit() after # the child code is run, or you will continue back into the parent codebase!!! # # YANOTE: reread the above -- USE CORE::exit() ESPECIALLY when running under mod_perl, otherwise # you'll create zombie Apache child processes that don't clean up properly! # # (MBB) I have updated this routine with information found at: # under the Forking section. See there for more info. The NOTEs above still apply, esp. # the use of CORE::exit() after child completion. # sub ForkMe { # Fork and return defined ( my $kid = fork() ) or die "Can't fork: $!\n"; if( $kid ) { # Parent process # Wait for the kid waitpid( $kid, 0 ); return( 0 ); } else { # To completely disassociate, need to do one more fork. defined ( my $grandkid = fork() ) or die "Kid cannot fork: $!\n"; if( $grandkid ) { # Original kid. Time to die. CORE::exit(); } else { # Grandkid. A kid of init now hopefully :-) # Close bound sockets if running as server process if( exists $ENV{"MOD_PERL"} ) { my $r = Apache->request(); $r->cleanup_for_exec(); } # Move to a neutral directory chdir( '/' ) or die "Can't chdir to /: $!"; # Close open filehandles. You must reopen them in your # code if you need them. # # Note we keep STDERR open and inherited to append to # Apache's error log, as this is likely the most useful # default treatment. Reopen elsewhere for a dedicated # error output. close( STDIN ); close( STDOUT ); # Disassociate from parent by starting new session POSIX::setsid() or die "Can't start a new session: $!"; # Child process return( 1 ); } } } _______________________________________________________ Michael Burns Cosbit Technologies AIM: cmikeburns MSN: cmikeburns _______________________________________________________ Box 2173, Station M • Calgary, Alberta, Canada • T2P 2M4 |
- [Mason] Firing up parallel processes Karjala
- Re: [Mason] Firing up parallel processes John Romkey
- Re: [Mason] Firing up parallel processes Douglas Hunter
- Re: [Mason] Firing up parallel processes Larry Underhill
- Re: [Mason] Firing up parallel processes Michael Burns

