Perl threads - capturing value returned from sub

Discussion in 'Perl Misc' started by Eric, Feb 27, 2007.

  1. Eric

    Eric Guest

    Hello,

    I am using Perl threads to launch multiple executions of a command in
    parallel. The code to do this is:

    foreach my $Machine ($self->Machines) {
    my $thr = threads->new(\&doPowerAction, $Machine);
    }
    foreach my $t (threads->list()) {
    $t->join;
    }

    The sub referenced is:

    sub doPowerAction
    {
    my $machine = shift;

    my $runScript = `power.exp $machine`;

    if ($runScript =~ m/SUCCESS/) {
    return "SUCCESS";
    } elsif ($runScript =~ m/FAILURE/) {
    return "FAILURE";
    } else {
    return "INTERNAL_ERROR";
    }
    }

    The problem is that I don't seem to be able to figure out how to
    capture the return value in the calling routine. Does anyone know how
    to do this?

    Thanks in advance to all that respond.

    Eric
     
    Eric, Feb 27, 2007
    #1
    1. Advertisements

  2. Please read the posting guidelines for this group. Code you post should
    be readily runnable by copying and pasting.

    .... code snipped ... edited version below
    You need to store the returned values in a shared data structure.

    I had to write and auxillary script to simulate the external
    application.

    #!/usr/bin/perl

    use strict;
    use warnings;

    my @retvals = qw( SUCCESS FAILURE SOMETHING_ELSE );
    print $retvals[ @retvals * rand ], "\n";

    __END__

    Then, replace your script with:

    #!/usr/bin/perl

    use strict;
    use warnings;

    use threads;
    use threads::shared;

    my %status;
    share %status;

    my @machines = qw( apple orange banana pineapple cherry );

    for my $machine ( @machines ) {
    my $t = threads->new( \&action, $machine );
    $t->join;
    }

    use Data::Dumper;
    print Dumper \%status;

    sub action {
    my ($machine) = @_;

    my $output = `s.pl`;
    if ( $output =~ /SUCCESS/ ) {
    $status{ $machine } = 'SUCCESS';
    }
    elsif ( $output =~ /FAILURE/ ) {
    $status{ $machine } = 'FAILURE';
    }
    else {
    $status{ $machine } = 'INTERNAL ERROR';
    }

    return;
    }

    __END__

    C:\DOCUME~1\asu1\LOCALS~1\Temp\2> r
    $VAR1 = {
    'cherry' => 'SUCCESS',
    'banana' => 'SUCCESS',
    'apple' => 'FAILURE',
    'orange' => 'INTERNAL ERROR',
    'pineapple' => 'FAILURE'
    };
     
    A. Sinan Unur, Feb 27, 2007
    #2
    1. Advertisements

  3. Eric

    Eric Guest

    Cancel this one; I found the answer, which was to just assign a
    variable to the join:

    my $result = $t->join;

    Seems like I always have a breakthrough immediately after I post to
    this site! :)

    Eric
     
    Eric, Feb 27, 2007
    #3
  4. Eric

    Eric Guest

    Thanks for your response, Sinan. I'll give it a try.

    I didn't want to paste the entire code as I thought it would only add
    clutter.

    Eric
     
    Eric, Feb 27, 2007
    #4
  5. Eric

    zentara Guest

    Just to amplify slightly, you can return arrays too.
    #!/usr/bin/perl
    use warnings;
    use strict;
    use threads;
    use threads::shared;

    # join() does three things: it waits for a thread to exit,
    # cleans up after it, and returns any data the thread may
    # have produced.

    my $thr = threads->new(\&sub1);

    my $return = $thr->join;

    print "Thread returned @$return\n";

    #hold for key input
    <>;
    ##########################################################
    sub sub1 {
    my @values = ('1',2, 'ten');
    print "@values\n";

    while(1){sleep 1}

    return \@values;
    }

    __END__
     
    zentara, Feb 27, 2007
    #5
  6. Eric

    Eric Guest

    Thanks - this is useful information.

    Eric
     
    Eric, Feb 27, 2007
    #6
  7. Eric

    anno4000 Guest

    What you really do is, you assign the value of ->join to a variable.

    This may sound like nit-picking, but taken literally (not just as
    a slip of the fingers) your description would reveal a fundamental
    misunderstanding of the meaning of "assign" in this usage.

    Anno
     
    anno4000, Feb 27, 2007
    #7
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.