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

I write an hadler for mod_perl.

The handler seems ok and it works well but if I create a thread inside this handler with fork the new thread will never destroy.

I include the following code as example :

$pid = fork(); if( $pid == 0 ) { my $p_pid; $p_pid = getppid; print "+START Child process: $$.$p_pid " ; sleep 1; print "+EXIT Child process: $$.$p_pid "; exit; } else { my $status_pid = 0; }

each time I create the thread I got a new instance of http, which will not disappear , even after exit

nobody 20873 20816 0 09:16 ? 00:00:00 /usr/local/apache/bin/httpd nobody 20874 20817 0 09:16 ? 00:00:00 /usr/local/apache/bin/httpd

Any suggestion ?

regards, Enzo

Edited by planetscape - added code tags; changed pre to code tags

( keep:2 edit:28 reap:0 )

Replies are listed 'Best First'.
Re: thread inside mod_perl handler will never been released
by jeteve (Pilgrim) on Jul 27, 2006 at 09:06 UTC

    Your father should wait for your child, otherwise the child might become a zombie... Brrrrr.

    see : fork

    If you really want the father to resign his soon, hence letting the son dying alone, consider the following code:

    #! /usr/bin/perl # # Playing with processes ... use POSIX qw(setsid); if ( $pid = fork()){ print "I am the father..\n"; print " Child pid : $pid \n"; } else{ setsid(); close STDIN ; # Inside a web server close STDERR ; # Idem close STDOUT ; # Idem print "\nI am the child \n"; print "I am $$\n"; $timer= 30 ; sleep($timer); print "\nWahhh, i am awake after $timer seconds \n"; } exit 0 ;
    Hope it helps.

    -- Nice photos of naked perl sources here !

      Using setsid and exit I got extra httpd daemon at each fork.

      So it doesn' seem a good solution

      If I use Core::exit(0) instead of exit I got an httpd daemon in zombie state.

      $pid = fork(); if( $pid == 0 ) { setsid(); # ----------------------------------------- close STDIN; close STDOUT; close STDERR; # ----------------------------------------- my $p_pid; $p_pid = getppid; ae_util::mylog( "START Child process: $$.$p_pid " ); sleep 1; ae_util::mylog( "EXIT Child process: $$.$p_pid " ); # CORE::exit(0); exit; }

      I found another solution which is more simple and seems to works well:

      $SIG{CHLD} = 'IGNORE';

      and

      $pid = fork(); if( $pid == 0 ) { # ----------------------------------------- close STDIN; close STDOUT; close STDERR; # ----------------------------------------- my $p_pid; $p_pid = getppid; ae_util::mylog( "START Child process: $$.$p_pid " ); sleep 1; ae_util::mylog( "EXIT Child process: $$.$p_pid " ); CORE::exit(0); }

      Do you known if that solution ( ignore SIGCHLD signal ) have some drawback ?

      Edited by planetscape - changed pre to code tags; added rudimentary formatting