[Chicago-talk] Do I need a fork for this?

Steven Lembark lembark at wrkhors.com
Sun Jan 25 14:56:36 PST 2009


Forks have an enormous coding advantage: you don't
have to understand threads to use them. Threading
in perl is somewhat easier than in many other
languages but isn't for the faint of heart.

They also don't require your copy of perl to be
compiled with threading enabled, which is a
general performance hit in any case.

Forks works most easily for handling a task that
has all of its information available when it
starts (e.g., cleaning out a temp directory all
you really need to know is the directory path).
In that case all you really care about is that
the job finished and whether it failed or not.

You can get the stats back with a CHLD handler
(see perldoc perlipc for an example). The basic
idea is that when the child process exits its
parent gets a SIGCHLD and can then look in $?
to find the status:

     $SIG{ CHLD }
     = sub
     {
         my $status  = $?;

         # check $status w/ code from perlipc
         # docs here.
     };

     ...

     if( my $pid = fork )
     {
         # parent may want to record the pid for
         # posterity -- or to kill running jobs
         # on exit. then again, it may not want
         # to bother...
     }
     elsif( defined $pid )
     {
         # child Does The Deed and then
         # [please pay attention] MUST
         # EXIT TO AVOID CAUSING A FORK
         # STORM AND CRASHING THE SYSTEM!

         my $status  = do_something @argz;

         exit $status || 0;
     }
     else
     {
         die "Phorkafobia: $!";
     }

Whatever you want done gets dealt with in the child.

This can also be helpful for dealing with things that
fail in ways that eval won't trap easily (i.e., they
crash your process): fork the child, let IT croak if
necessary, snag the exit status, and report it. In
that case you use a wait to get the child's exit
status:

     # notice the lack of $SIG{ CHLD }

     my $running_pidz = ();

     sub phork_a_job
     {


         if( my $pid = fork )
         {
             $running_pidz{ $pid } = $exit_message;
             ...
         }
         elsif( define $pid )
         {
             ...
         }
         else
         {
             die "Phorkafobia: $!";
         }

         if( ( my $pid = wait ) > 0 )
         {
             # there was something to wait for.

             my $status = $?;

             my $message = $running_pidz{ $pid };

             # dissect $status

             if( $clean )
             {
                 print "Your $message completed";
             }
             else
             {
                 carp "Your $message filed: $reason";
             }

         }
     }

-- 
Steven Lembark                                            85-09 90th St.
Workhorse Computing                                 Woodhaven, NY, 11421
lembark at wrkhors.com                                      +1 888 359 3508


More information about the Chicago-talk mailing list