http://qs1969.pair.com?node_id=288491

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

Well, that's about the best title i could think of...

I have a program that spawns a bunch of processes that send data back to the parent via a named pipe. This seemed to work fine until a came across a bug that, after many hours of reducing code to duplicate the problem, appears to have the following effect:

When the pipe contains a certain amount of (unread) data, usually around 10K, wait will hang indefinitely.

My code:

#! /usr/bin/perl use strict; use warnings; my $NUMLOOPS = 250; my $MAXPROCESS = 10; my $DATALEN = 100; my $VERBOSE = 1; # -------------------------------------- my( %pid ); pipe( CHILD, PARENT ); if(! $VERBOSE ) { close( STDERR ) } foreach my $num ( 1 .. $NUMLOOPS ) { print STDERR ">$num> processing\n"; if( keys( %pid ) >= $MAXPROCESS ) { print STDERR ">$num> waiting for reap\n"; &reap(); } if( my $pid = fork() ) { print STDERR ">$num> forked\n"; $pid{$pid} = $num; } else { close( CHILD ); print PARENT "x" x $DATALEN . "\n"; close( PARENT ); select( '', '', '', rand ); print STDERR ">$num> finished\n"; exit 0; } } while( %pid ) { &reap() } close( PARENT ); print "parent received: "; while( my $child = <CHILD> ) { print "."; } print "\n"; close( CHILD ); sub reap { my( $pid ) = wait(); if( $pid == -1 ) { die( "no more kids to reap!\n" ) } if(! $pid{$pid} ) { die( "why did I see $pid?\n" ) } print STDERR ">$pid{$pid}> reaped\n"; delete( $pid{$pid} ); }
On my system (v5.6.1, solaris), this code will produce the following:
...<snip>... >101> processing >101> waiting for reap >88> finished >88> reaped >101> forked >102> processing >102> waiting for reap >84> finished >84> reaped >102> forked >103> processing >103> waiting for reap *hangs*
If i increase $MAXPROCESS to 20, it hangs at 113 instead (10 more). If i double $DATALEN, it hangs at 57 (roughly half).

I don't claim to be an expert at multi-processes or ipc, although i would assume a pipe should be able to hold more than 10K at a time... Or is there something obvious i'm missing? Any help appreciated!

- ><iper

my JAPH: print"Just another Perl hacker\n"; # ^ look, no space! pretty tricky huh?