#!/usr/bin/perl # prime-fork - demo silly prime number finder # using forks. sub forksub(&); use strict; main(); exit; sub main { my($head,$tail) = queue(); my $kid = forksub { close($tail); check_num($head, 2) }; close $head; for (my $i = 3; $i <= 1000; $i++) { enqueue($tail, $i); } close $tail; waitpid($kid,0); } sub check_num { my ($stream, $cur_prime) = @_; my ($spawned, $num); my($head, $tail) = queue(); while ($num = dequeue($stream) ) { next unless $num % $cur_prime; if ($spawned) { enqueue($tail, $num); next; } print "Found prime $num\n"; $spawned = forksub { close($tail); check_num($head, $num) }; close $head; } close($head) unless $spawned; close($tail); waitpid($spawned,0) if $spawned; exit; } sub forksub(&) { my $coderef = $_[0]; my $pid = fork(); die "cannot fork: $!" unless defined $pid; return $pid if $pid; goto &$coderef; # don't need no stinkin' stack frames } sub queue { local(*READER, *WRITER); pipe(READER, WRITER) || die "can't pipe: $!"; return (*READER, *WRITER); } sub enqueue(*$) { my ($stream, $n) = @_; syswrite($stream, pack("L", $n), 4); # XXX: errno } sub dequeue(*) { my ($stream) = @_; my $n; sysread($stream, $n, 4) == 4 || return; unpack("L", $n); }