Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Re: How to tell a child what to do?

by Anonymous Monk
on Sep 21, 2005 at 09:43 UTC ( #493708=note: print w/ replies, xml ) Need Help??


in reply to How to tell a child what to do?

The standard way of doing this is using pipe opens. man perlipc has some examples - the example uses communication between the parent and a single child, but filehandles can easily be saved in a datastructure.

Note that if you use pipe-open, open returns the PID of the child. To determine a child terminating, set up a signal handler to catch SIGCLD. This signal doesn't tell you the pid, but if you do a wait or a waitpid in the handler, you do. Given the PID of the terminated child, you know which task was assigned to it (assuming you stored this information when dealing out the tasks).

Study man perlipc, it's a real treasure trove. It should have enough examples to get you on your way.


Comment on Re: How to tell a child what to do?
Re^2: How to tell a child what to do?
by Eyck (Priest) on Sep 21, 2005 at 10:12 UTC
    You are surprisingly right,

    I somehow always regarded

    $pid = open(KID_TO_WRITE, "|-");
    trick as a way to talk with only one child, but if we rewrite it like this:
    $fh = new FileHandle; my $sleep_count = 0; do { $pid = open($fh, "|-"); unless (defined $pid) { warn "cannot fork: $!"; die "bailing out" if $sleep_count++ > 6; sleep 10; } } until defined $pid; my (@some_data)=qw[a be ce]; if ($pid) { print $fh @some_data; close($fh) || warn "kid exited $?"; } else { while (<STDIN>) { print "GOT: $_\n"; # child's STDIN is parent's KID } exit; # don't forget this };
    then we get to hold whole array of different $fd's, each for talking with one child. This would be clean and reliable, exactly what I wanted.

    Thanx.

      on second thought..this doesn't work that well with more then one fd open...it hangs on close($fd). Maybe there's an error in my code:
      print "I'm $$\n;"; use FileHandle; $fh = new FileHandle; $fh1 = new FileHandle; my $sleep_count = 0; do { $pid = open($fh, "|-"); unless (defined $pid) { warn "cannot fork: $!"; die "bailing out" if $sleep_count++ > 6; sleep 10; } } until defined $pid; if ($pid) { print "I'm master($$) $pid...\n"; } else { print "Waiting for commands($$)..\n"; while (<STDIN>) { print "GOT: $_\n"; # child's STDIN is parent's KID } exit; # don't forget this }; do { $pid1 = open($fh1, "|-"); unless (defined $pid1) { warn "cannot fork: $!"; die "bailing out" if $sleep_count++ > 6; sleep 10; } } until defined $pid1; if ($pid1) { print "I'm master($$) $pid1...\n"; } else { print "Waiting for commands($$)..\n"; while (<STDIN>) { print "GOT: $_\n"; # child's STDIN is parent's KID } exit; # don't forget this }; my (@some_data)=qw[a be ce]; print "($$)PID: $pid\n"; print $fh @some_data; print "($$) printing done, let's close:\n"; close($fh) || warn "kid exited $?"; print "($$)PID: $pid1\n"; print $fh1 @some_data; print "($$) printing done, let's close:\n"; close($fh1) || warn "kid exited $?"; print "END FH TEST\n\n\n";
        I wrote it slightly differently, and it seems to work for me:
        #!/usr/bin/perl use strict; use warnings; print "I'm the master ($$)\n"; my %pids; my $children = 2; for my $x (1 .. $children) { my ($fh, $pid); my $tries = 6; do {$pid = open $fh, "|-"; unless (defined $pid) { warn "fork: $!\n"; die "bailing out" unless $tries--; sleep 5; } } until defined $pid; if ($pid) { print "I'm master ($$) of child ($pid)\n"; $pids {$pid} = $fh; } else { printf "I'm a child ($$) of master (%d)\n", getppid; while (<>) { chomp; printf "Child ($$) received: [%s]\n", $_; } print "Child ($$) exiting\n"; exit; } } my $count = 0; while (my ($pid, $fh) = each %pids) { my $data = sprintf "[[%02d]]", ++$count; printf "Sending data %s to child (%d)\n", $data, $pid; print $fh $data, "\n"; } while (my ($pid, $fh) = each %pids) { printf "Closing handle to child (%d)\n", $pid; close $fh or warn "Failed to close handle for child ($pid)\n"; } print "Last line\n"; __END__ I'm the master (19054) I'm a child (19055) of master (19054) I'm master (19054) of child (19055) I'm a child (19056) of master (19054) I'm master (19054) of child (19056) Sending data [[01]] to child (19056) Sending data [[02]] to child (19055) Closing handle to child (19056) Child (19056) received: [[[01]]] Child (19056) exiting Closing handle to child (19055) Child (19055) received: [[[02]]] Child (19055) exiting Last line

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://493708]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (8)
As of 2014-08-20 13:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (113 votes), past polls