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

Hi. What I have is a script that I first started on when I was completely new to perl. It has gotten fairly large, several subroutines and whatnot, centered around the Net::AIM module. At the time, I don't think that I understood the concept of fork(), but it sounded like what I needed to easily have more than one of my scripts running at once. Now it seems like I have a problem...
I have a seperate script to use fork to spawn several instances of the main script, and replace them when they exit. It looks a little like this:
my $counter; for ($counter = 1; $counter <= 3; $counter++) { $pid = fork(); if ($pid) { $child{$pid} = $counter; } else { exec "perl main.pl arg1 arg2"; exit $counter; } } while ($counter) { $doneproc = wait(); $doneval = $? >> 8; $pid = fork(); if ($pid) { $child{$pid} = $counter; $counter++; } else { exec "perl main.pl arg1 arg2"; exit $counter; } }
Now, this works great. But after doing some reading this morning, I'm wondering if there's a way to get around using the exec line. If possible, I would like to avoid the overhead cost of having several perl.exe instances active. It seems like the way I'm doing things is contradictory to the purpose of fork. Am I wrong? .. or what should I do? The way Net::AIM works, it looks like it's beyond my capabilities to rewrite the script in a way that it can be properly forked... I'm confused, and my brain hurts. Help! Thanks, Berto.

Replies are listed 'Best First'.
Re: Yet another fork() w/ win32 (activeperl) question
by Anonymous Monk on May 24, 2003 at 20:42 UTC
    I guess I posted a bit too soon, I have something which seems to work. Can anybody tell me whether or not i'm doing the forking right?
    #!c:\perl\bin\perl use Net::AIM; use strict; use warnings; my $counter = 0; my $done; while (1==1) { if ($counter <= 3) { my $pid = fork(); if ($pid) { print "forking process $counter.\n"; $counter++; } else { ############meat########################### # pretty much just # straight copy/pasted from main script ###########/meat########################### exit $counter; } } else { $done = wait(); $counter--; } }
    It seems to work brilliantly.
      Since you are running on windows, fork() isn't exactly forking a new process, it forks a pseudo-process. However it looks to be correct if you want to spawn multiple copies of the same script. When the original script terminates so do the child processes as they live in the memory of the parent process. One way to get around this is to use Win32::Process with the DETACHED_PROCESS flag, if you want the children to live on.