hi there,

I'm trying to use fork in a script that batch converts my old taped Simpsons 
episodes to dvd. 

This is the first time I've used fork and I'm a bit bewildered by the behaviour 
exhibited 
when a child process dies.

Basically, I want the main process to fork a list of children(one for each 
video file) 
but not to wait until the child dies before the next fork.
Then when the child dies I want it logged.

As you can see from my code I've installed a SIG{CHLD} handler 
(which I found in the perlipc manpage):

        #!/usr/bin/perl -w
        use strict;
        use POSIX ":sys_wait_h";

        $SIG{CHLD} = \&REAPER;
        sub REAPER
        {
            my $stiff;
            while(($stiff = waitpid(-1, WNOHANG)) > 0)
            {
                print LOG "Child process no. $stiff exited with status $?\n";
            }
            $SIG{CHLD} = \&REAPER;
        }

        open LOG, ">> /home/rools/Video/simpsons/log" or die "Can't open log 
file: $!";

        my $dir = "/home/rools/Video/simpsons";

        my @files;

        opendir DH, $dir or die "Can't open Video dir: $!";

        for (readdir DH)
        {
            (/^Simpsons_\d+$/)? push @files, $_ : next;
        }
        closedir DH;

        print LOG "Simpsons episodes:\n", map "$_\n", @files;
       
        for my $file(@files)
        {
            defined(my $pid = fork) or die "Can't fork for $file: $!";
            unless($pid)
            {
                $file =~ /^Simpsons_(.+)$/;
                my $episode = "Sim_".$1;
                exec("tovid", "-pal", "-in", "$dir/$file", "-out", "$episode"); 
 
                die "Can't execute tovid for process no $$ on file  $file: $!";
            }
            else
            {
                print LOG "Forked child process no. $pid for file $file.\n";
            }
            $SIG{CHLD} = \&REAPER;
        }

Tovid executes successfully for both files but when the encoding is finished 
the parent process just hangs there.

The program is forking the children in parallel as can be seen from the tovid 
output 
as well as from tailing log

The SIG{CHLD} handler doesn't get called at all since the output from
    print LOG "Child process no. $stiff exited with status $?\n";
is missing.
As you can see I've tried putting in another $SIG{CHLD} at the end but to no 
avail.

I have found the following text in the perlfork manpage:

  Calling exec() within a pseudo-process actually spawns the requested 
executable in a separate
  process and waits for it to complete before exiting with the same exit status 
as that process.
  This means that the process ID reported within the running executable will be 
different from 
  what the earlier Perl fork() might have returned.

but then in Randal and Tom's Learning Perl(3rd edition) about exec "bedrock" on 
p.196:

  When we reach the exec operation, Perl locates bedrock and "jumps into it".
  At that point, there is no Perl process any more*, just the process running 
the 
  bedrock command.
  *Actually, it's the same process, having performed the Unix exec(2) system 
call. 
  The process ID remains the same.

Since the exec'ed process doesn't retain the same PID as what forked returned, 
how can my waitpid
ever reap the correct child process ?

I'm trying hard to get my head around this and would really appreciate your 
input.


Cornelis



--memento mori


-- 
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>


Reply via email to