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. Advertising

  2. "Eric" <> wrote in news:1172538201.694433.133140
    @j27g2000cwj.googlegroups.com:

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


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

    .... code snipped ... edited version below

    > 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?


    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'
    };


    --
    Sinan
    A. Sinan Unur, Feb 27, 2007
    #2
    1. Advertising

  3. Eric

    Eric Guest

    On Feb 26, 5:03 pm, "Eric" <> wrote:
    > 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


    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

    On Feb 26, 5:21 pm, "A. Sinan Unur" <> wrote:
    > "Eric" <> wrote in news:1172538201.694433.133140
    > @j27g2000cwj.googlegroups.com:
    >
    > > I am using Perl threads to launch multiple executions of a command in
    > > parallel. The code to do this is:

    >
    > Please read the posting guidelines for this group. Code you post should
    > be readily runnable by copying and pasting.
    >
    > ... code snipped ... edited version below
    >
    > > 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?

    >
    > 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'
    > };
    >
    > --
    > Sinan


    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

    On 26 Feb 2007 17:24:40 -0800, "Eric" <> wrote:


    >
    >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


    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__


    --
    I'm not really a human, but I play one on earth.
    http://zentara.net/japh.html
    zentara, Feb 27, 2007
    #5
  6. Eric

    Eric Guest

    On Feb 27, 7:21 am, zentara <> wrote:
    > On 26 Feb 2007 17:24:40 -0800, "Eric" <> wrote:
    >
    >
    >
    > >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

    >
    > 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__
    >
    > --
    > I'm not really a human, but I play one on earth.http://zentara.net/japh.html


    Thanks - this is useful information.

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

    -berlin.de Guest

    Eric <> wrote in comp.lang.perl.misc:
    > On Feb 26, 5:03 pm, "Eric" <> wrote:


    > Cancel this one; I found the answer, which was to just assign a
    > variable to the join:
    >
    > my $result = $t->join;


    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
    -berlin.de, Feb 27, 2007
    #7
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. THY
    Replies:
    1
    Views:
    390
    Steve C. Orr, MCSD
    Aug 19, 2003
  2. Ben
    Replies:
    2
    Views:
    867
  3. Lawrence D'Oliveiro

    Death To Sub-Sub-Sub-Directories!

    Lawrence D'Oliveiro, May 5, 2011, in forum: Java
    Replies:
    92
    Views:
    1,980
    Lawrence D'Oliveiro
    May 20, 2011
  4. mike
    Replies:
    3
    Views:
    177
  5. Replies:
    3
    Views:
    79
    David Dorward
    Jan 20, 2006
Loading...

Share This Page