• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 429
  • Last Modified:

Forking and return values

I am trying to find a way to run some code asynchronously in Perl, but have the ability to return some non-scalar return values from the asynchronous code. In my situation, I can't use ithreads (too much memory usage). I have tried a number of modules (forks.pm, Parallel::Simple, Parallel::ForkManager), but none of these seem to allow me to return a hash reference from the asynchronous code. Basically, the only thing I can get back from this code is an integer.

Is there any way for the forked code to share a given variable (so I can add the return values to it), or ideally return something like a hash reference?

Here is some sample code with Parallel::ForkManager:

my @responses;
my $pm = new Parallel::ForkManager(scalar @jobs);
foreach my $agent (@jobs) {
    my $pid = $pm->start and next;
    my $response = _threadedRun($testMethod, $agent);
    push @responses, $response;
    $pm->finish;
}

The problem with this is that the @responses array doesn't grow, it seems to be copied per forked process and I am unable to gather the return values.

Any help would be very much appreciated.
0
timdr
Asked:
timdr
  • 2
  • 2
1 Solution
 
ps15Commented:
you can try something like:



use warnings;
use strict;
use IO::Select;
use IO::Socket;

my (@thread_read,@thread_write); # Sockets
my (threads);

# Start the Threads
foreach ( 0 .. ( $threads - 1 ) ) {
    pipe( $thread_read[$_], $thread_write[$_] );
    if (fork) { next; }
    { # This code is the "child" code
        close $thread_read[$_];
        thread_start( $thread_read[$_]  );
      print {$thread_write[$_]} "\nEND\n";
        exit;
    }
}

# close the writeing parts of the pipes
foreach (@thread_write) { close($_); }

# Initiate non-blocking IO
my $select = IO::Select->new();
foreach (@thread_read) { $select->add($_); }

# wait for threads to die
while ($threads) {
    if ( my @ready = $select->can_read(0) ) {
        foreach (@ready) {
            my $line = <$_>;
            if ( defined($line) ) {
                chomp $line;
            # here you can collect information of your threads.
                if ( $line =~ /END/ ) { $threads--; }
            }
        }
    }
}


sub thread_start {
      my $output = shift;
      # do stuff, write stuff to $ouput
}
0
 
ozoCommented:
my @jobs=(1..5);
my @fork;
for my $agent ( @jobs ){
    local *F;
    unless( open F,"-|" ){
        print response($agent) ; exit;
    }
    push @fork,*F;
}
my @responses;
for( @fork ){
    push @responses,<$_>;
    close $_;
}
sub response{
    return "$$ @_";
}
print join"\n",@responses;
0
 
timdrAuthor Commented:
Is there any way without writing text, but instead returning a hash reference?
0
 
ps15Commented:
you could serialize the hash with Data::Dumper os simular...
0
 
timdrAuthor Commented:
interesting idea, thanks!
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 2
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now