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

I have been trying to write a script for data processing that includes a point where, based upon the input data, two threads may be running simultaneous. Then upon the closure of those two threads, the processing is again the same. I read the posting from Jan 2002, and accomplished the fork. However, I found that as soon as the script proceeds down the fork, the script finishes. The processing is done correctly, but I not until after the script has finished.

Essentially, this is the structure:

`command one *` `command two *` if (file =~ AAA) { `command four option1 file` &finish }elsif (file =~ BBB) { `command four option2 file` &finish } `command five` sub finish { `command six` }
I find that command five runs three times. I would expect it to only run once. All files will be of either AAA or BBB, but not both. The finish subroutine will run twice for files of type BBB and once for type AAA.

What did I screw up?

Replies are listed 'Best First'.
Re: forking patience...
by sauoq (Abbot) on Jun 19, 2003 at 20:40 UTC
    I find that command five runs three times.

    If your perl code is structured like that pseudo code, "command five" will only run once. Unfortunately, there's no way for us to tell what the problem is with your actual code because you didn't provide it.

    You'll probably get the help you need if you show us your real code. The response will also be quicker and easier on the editors if you wrap it in <code></code> tags.

    -sauoq
    "My two cents aren't worth a dime.";
    
Re: forking patience...
by waswas-fng (Curate) on Jun 19, 2003 at 20:44 UTC
    Sounds like you really want threads not forking. Take a look at threads if you are using Perl 5.8. You just spawn the threads, let them work and then join them before moving on to the rest of your script.

    -Waswas
Re: forking patience...
by bobn (Chaplain) on Jun 20, 2003 at 03:23 UTC
    NO way to know without the code, but since you say 'fork' in the title, my guess is that you are failing to exit; in the child processes. Without this, all the proccess complete from where the fork happened executing all the rest of the porgram, hence 'command 5' happens more than you expect.

    The fact that I've made that mistake, oh, 10 or 15 times, also leads me to that suspicion.

    --Bob Niederman, http://bob-n.com
      Many apologies in advance for the obfuscation...
      #!/opt/local/bin/perl -w open(STDERR, ">errors.log") || die "cannot create error log"; $dir = `pwd`; chomp $dir; if ($dir =~ m/(^.*)(GQ.*)/) { $path = $1; $lib = $2; }; chop $path; $xpath = "$path/ProjectSpecificInfo/"; print "working from $dir\n"; print "library is $lib\n"; opendir (DIR, ".") || die "cannot read from current dir"; open (XREF, "<$xpath$lib.OUT") || die "cannot open cross-ref file $xpa +th$lib.OUT"; %XREF = (); while (<XREF>) { ($SeqID, $MNid) = (split /\t/, $_)[0,1]; $XREF{$SeqID} = $MNid; }; `phred -pd phd_dir *.gz`; `phran -q $phran_cut phd_dir/*.phd.1`; `mv $dir/phd_dir/*.raw $dir/phd_dir/phran_dir/`; print "raw files moved to phran, now sorting\n"; while ($sequence = readdir (DIR)) { if ( $sequence =~ /MN/ ) { if ( $sequence =~ /(^.*)(\.gz)/ ) { $sequence = $1; }; if (exists $XREF{$sequence}) { $seqID = $XREF{$sequence}; if ($seqID =~ TB) { `mv $dir/phd_dir/phran_dir/$sequence.raw $dir/phd_dir/phra +n_dir/3prime/`; } else { `mv $dir/phd_dir/phran_dir/$sequence.raw $dir/phd_dir/phra +n_dir/5prime/`; }; }; }; }; $threeprimedir = "$dir/phd_dir/phran_dir/3prime"; $fiveprimedir = "$dir/phd_dir/phran_dir/5prime"; @primes = ($threeprimedir, $fiveprimedir); foreach $vfdir ( @primes ) { $pid = fork and next; &VF4($line); print "Completed $dir\n"; }; print "processing complete for $dir\n"; $dir/phd_dir/phran_dir/vf_dir/`; sub finish { chdir "$dir/phd_dir/phran_dir/vf_dir/"; print "Running artifact filter\n"; `af *.seq > afresults.log`; `mv *qc $dir/phd_dir/phran_dir/vf_dir/af_dir/`; `mv afresults.log $dir/phd_dir/phran_dir/vf_dir/af_dir/`; `mv *.af.out $dir/phd_dir/phran_dir/vf_dir/af_dir/`; `mv $dir/phd_dir/phran_dir/vf_dir/*.raw $dir/phd_dir/phran_d +ir/`; }; sub VF4($) { if ($vfdir =~ /3prime/) { chdir "$dir/phd_dir/phran_dir/3prime"; `gstVF4 -o $vffile3 *.raw > 3primevf.log`; print "finished Running VF4 in 3prime\n"; `mv $dir/phd_dir/phran_dir/3prime/* $dir/phd_dir/phran_dir/vf_dir/ +`; chdir ".."; `rm $vfdir`; #&finish; }elsif ($vfdir =~ /5prime/) { chdir "$dir/phd_dir/phran_dir/5prime"; `gstVF4 -o $vffile5 *.raw > 5primevf.log`; print "finished Running VF4 in 5prime\n"; `mv $dir/phd_dir/phran_dir/5prime/* $dir/phd_dir/phran_dir/vf_dir/ +`; chdir ".."; `rm $vfdir`; #&finish; }; &finish; };