Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask

<> operation with pipes

by seefurst (Initiate)
on May 08, 2012 at 15:45 UTC ( #969488=perlquestion: print w/replies, xml ) Need Help??
seefurst has asked for the wisdom of the Perl Monks concerning the following question:

So consider the following: It's not really secure, so don't use it. It's not Taint safe, it's just for discussion (let me know if this is the wrong section, apologies in advance).
use strict; use Parallel::ForkManager; use IO::Handle; my ($something, $somemaxnum) = @ARGV; pipe(DAREADER, DAWRITER); DAREADER->autoflush(1); DAWRITER->autoflush(1); sub onFinish { while (<DAREADER>) { ## read data from children print; } } my $fkmngr = new Parallel::ForkManager($somemaxnum); $fkmngr->run_on_finish(\&onFinish); for (1..$something) { $fkmngr->start and next; # child close DAREADER; print DAWRITER "some text"; close DAWRITER; } close DAWRITER; $fkmngr->wait_all_children; close DAREADER; __END__
Ok so this script deadlocks. Can anyone guess why?

What I find is this. With a short amount of text, it's fine.. but when the text gets larger or the forks end at various times the run_on_finsh subroutine doesn't leave the while loop. The while loop actually reads data from multiple forks, not just the one that finished (run_on_finish tells you the pid that just finished. On a few occations this number did not change yet data indicated that it was reading writes from a different fork which means that the funciton was executed once, after one fork ended).

However, the forks are still <defunct> (on solaris... ymmv), but the parent process is waiting for a read. Which means that <> is broken, I think, with pipes, because even though each fork has sent a close() to DAREADER, the parent process never receives EOF, and thus the subroutine never exits, wait() is never called.. etc... I mean yes, each file handle is copied however wouldn't close() send EOF down the pipe? Is this really broken or am I missing something?

The way I've worked around it is do ye olde 'dot-alone-on-a-line' trick and have each fork send a final "\n." which calls a last in the onFinish subroutine:

sub onFinish { while (<DAREADER>) { last if /^\.$/; print; } }
This will exit the subroutine, allow wait() to be callled, new forks to start and Parallel::ForkManager to do its thing (a great great module IMO!), however I can only guess why I need to do this DGRAM style and EOF just isn't failing the <> test.

Replies are listed 'Best First'.
Re: <> operation with pipes
by zwon (Abbot) on May 08, 2012 at 16:21 UTC

    You should add an exit statement in the end of the loop.

Re: <> operation with pipes
by tobyink (Abbot) on May 08, 2012 at 16:05 UTC

    I may well be completely on the wrong track, but $|?

    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://969488]
Approved by Old_Gray_Bear
Front-paged by Old_Gray_Bear
[marto]: hey Corion, good weekend?
[prospect]: Thank you
[marto]: no problem prospect
[Corion]: I hope you all spent a good weekend!
[Discipulus]: good morning eumonks!
[Discipulus]: yes thanks, mostly at seaside, but the waterpolo tournemts went bad, very bad.. ;=(
[marto]: hey Discipulus, Corion a reasonable weekend. The boys first trip to the cinema
[Corion]: Discipulus: You got pushed too much under water?
[Corion]: marto: Oooh - cinema... I guess that's something I could do with my godson and sibling and sister as well, but I guess that getting a six year old and two four year olds into one movie is a tough sell ;)
[marto]: busy weekend, no me time :P

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (9)
As of 2017-07-24 08:06 GMT
Find Nodes?
    Voting Booth?
    I came, I saw, I ...

    Results (348 votes). Check out past polls.