Perl threads in Object Oriented code

Discussion in 'Perl Misc' started by Eric, Apr 30, 2007.

  1. Eric

    Eric Guest

    Hello,

    I have a Perl script that utilizes Perl threads to run a function
    (time) on a list of entities. Using Perl threads will allow the code
    to run in parallel (as opposed to serially) and therefore minimize the
    time it takes to run through the list.

    The code does something similar to what the following code is doing:

    ============= Perl script =============

    #!/usr/bin/perl

    use strict;
    use warnings;

    use threads;
    use threads::shared;

    my @clocks = ("clock1", "clock2", "clock3");

    foreach my $clock (@clocks) {
    my $thr = threads->new(\&get);
    sleep 1;
    }

    for my $t (threads->list()) {
    my $result = $t->join;
    }

    sub get {
    my $time = shift;
    $time = time();
    print STDOUT "The time is: $time\n";
    return;
    }
    =======================================

    Now, I want to get this script working in object oriented code. The
    following scripts (plagiarized from a Perl book for the sake of
    correctness) are doing something similar as the code above, but is
    running the time function on the entities in serial, not parallel:

    The Perl script is:

    ============= Perl script =============
    #!/usr/bin/perl

    use strict;
    use warnings;

    use Clock;

    my @clocks = ("clock1", "clock2", "clock3");

    foreach my $clock (@clocks) {
    my $clock = new Clock();
    sleep 1;
    print STDOUT "\$clock is: ". $clock->get(), "\n";
    }
    =======================================

    And the Perl module being used is:

    ============= Perl module: Clock.pm =============
    #!/usr/bin/perl

    package Clock;

    use strict;
    use warnings;

    sub new {
    my ($type) = @_;
    my $self = {};
    $self->{time} = time();
    bless $self, $type;
    }

    sub get {
    my ($self) = shift;
    return($self->{time});
    }

    1;
    =======================================

    Note the following line of code in the former (non OO) script:

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

    This line is calling the 'get' sub. So, if I were to use the OO
    scripts shown, how should I implement this?

    I tried doing the obvious, which was to change the line to:

    my $thr = threads->new($clock->get());

    But I got the following error:

    thread failed to start: Undefined subroutine &main::1177952602 called
    at ./CC.pl line 19.

    Other failed attempts were:

    my $thr = threads->new(\&clock->get());
    my $thr = threads->new(Clock::clock->get());
    my $thr = threads->new($Clock::get());

    Truthfully, I am not well versed at Object Oriented Perl (or anything
    else). So at this point I was making guesses that weren't so educated.

    Does anyone have a solution?

    Thanks in advance to all that respond.

    Eric
     
    Eric, Apr 30, 2007
    #1
    1. Advertising

  2. On Mon, 30 Apr 2007 11:19:35 -0700, Eric wrote:

    >
    > Note the following line of code in the former (non OO) script:
    >
    > my $thr = threads->new(\&get);
    >
    > This line is calling the 'get' sub. So, if I were to use the OO scripts
    > shown, how should I implement this?
    >
    > I tried doing the obvious, which was to change the line to:
    >
    > my $thr = threads->new($clock->get());
    >
    > But I got the following error:
    >
    > thread failed to start: Undefined subroutine &main::1177952602 called at
    > ./CC.pl line 19.
    >
    > Other failed attempts were:
    >
    > my $thr = threads->new(\&clock->get()); my $thr =
    > threads->new(Clock::clock->get()); my $thr =
    > threads->new($Clock::get());
    >
    > Truthfully, I am not well versed at Object Oriented Perl (or anything
    > else). So at this point I was making guesses that weren't so educated.
    >
    > Does anyone have a solution?


    Try (untested):
    threads->new(sub { clock->get(); });
    or
    threads->new(Clock::get, clock);

    Your problem is that the method wants a first parameter, the self
    parameter or iow the object it is invoked on. You *have* to pass that
    parameter, above are two ways of doing that.

    HTH,
    M4
     
    Martijn Lievaart, Apr 30, 2007
    #2
    1. Advertising

  3. Eric

    Guest

    Eric <> wrote:
    >
    > Note the following line of code in the former (non OO) script:
    >
    > my $thr = threads->new(\&get);
    >
    > This line is calling the 'get' sub. So, if I were to use the OO
    > scripts shown, how should I implement this?
    >
    > I tried doing the obvious, which was to change the line to:
    >
    > my $thr = threads->new($clock->get());
    >
    > But I got the following error:
    >
    > thread failed to start: Undefined subroutine &main::1177952602 called
    > at ./CC.pl line 19.


    I doubt you will get the performance you think you will out of this
    strategy. Starting a new thread for each task is generally a losing
    proposition in Perl. Anyway, try:

    my $thr = threads->new(sub{$clock->get()});

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
     
    , Apr 30, 2007
    #3
  4. Eric

    Eric Guest

    wrote:
    > Eric <> wrote:
    > >
    > > Note the following line of code in the former (non OO) script:
    > >
    > > my $thr = threads->new(\&get);
    > >
    > > This line is calling the 'get' sub. So, if I were to use the OO
    > > scripts shown, how should I implement this?
    > >
    > > I tried doing the obvious, which was to change the line to:
    > >
    > > my $thr = threads->new($clock->get());
    > >
    > > But I got the following error:
    > >
    > > thread failed to start: Undefined subroutine &main::1177952602 called
    > > at ./CC.pl line 19.

    >
    > I doubt you will get the performance you think you will out of this
    > strategy. Starting a new thread for each task is generally a losing
    > proposition in Perl. Anyway, try:
    >
    > my $thr = threads->new(sub{$clock->get()});
    >
    > Xho
    >


    Someone made a similar suggestion, but it seems as if you are
    redefining the sub in the file in which it is being called instead of
    using it from it's current module(?). Am I missing something here?

    Eric
     
    Eric, Apr 30, 2007
    #4
  5. Eric

    Guest

    Eric <> wrote:
    > wrote:
    > > Eric <> wrote:
    > > >
    > > > Note the following line of code in the former (non OO) script:
    > > >
    > > > my $thr = threads->new(\&get);
    > > >
    > > > This line is calling the 'get' sub. So, if I were to use the OO
    > > > scripts shown, how should I implement this?
    > > >
    > > > I tried doing the obvious, which was to change the line to:
    > > >
    > > > my $thr = threads->new($clock->get());
    > > >
    > > > But I got the following error:
    > > >
    > > > thread failed to start: Undefined subroutine &main::1177952602 called
    > > > at ./CC.pl line 19.

    > >
    > > I doubt you will get the performance you think you will out of this
    > > strategy. Starting a new thread for each task is generally a losing
    > > proposition in Perl. Anyway, try:
    > >
    > > my $thr = threads->new(sub{$clock->get()});
    > >
    > > Xho
    > >

    >
    > Someone made a similar suggestion, but it seems as if you are
    > redefining the sub in the file in which it is being called instead of
    > using it from it's current module(?).


    sub{...} creates a new anonymous sub. It can't redefine any existing subs
    because to do that, you would need to use the name (or a ref to) an
    existing sub, which being anonymous this ones doesn't have.

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
     
    , Apr 30, 2007
    #5
  6. Eric

    Eric Guest

    wrote:
    > > Someone made a similar suggestion, but it seems as if you are
    > > redefining the sub in the file in which it is being called instead of
    > > using it from it's current module(?).

    >
    > sub{...} creates a new anonymous sub. It can't redefine any existing subs
    > because to do that, you would need to use the name (or a ref to) an
    > existing sub, which being anonymous this ones doesn't have.
    >
    > Xho


    Ok - I can see the rationale behind this. In fact, I tried it, and it
    worked. However, I got the oddest response message I've ever seen:

    Attempt to free unreferenced scalar: SV 0xafc2db8, Perl interpreter:
    0xaa069a0 at <file> <line>

    (where 'file' and 'line' were removed in the above).

    I should tell you that I got this message running different code than
    that which I provided in my posting. So I will need to investigate
    what else is going on. I will also try it with the code I posted to
    see if I get the same error. But off hand, does the message indicate
    anything to you?

    Eric
     
    Eric, Apr 30, 2007
    #6
  7. Eric

    Eric Guest

    Martijn Lievaart wrote:
    >
    > Try (untested):
    > threads->new(sub { clock->get(); });
    > or
    > threads->new(Clock::get, clock);
    >
    > Your problem is that the method wants a first parameter, the self
    > parameter or iow the object it is invoked on. You *have* to pass that
    > parameter, above are two ways of doing that.
    >
    > HTH,
    > M4


    Thanks for your response. I did in fact try your first suggestion, and
    it worked, although I got an odd message (see my reply regarding
    this).

    I'll give the second one a try also once I determine the source of the
    aforementioned odd message.

    Eric
     
    Eric, Apr 30, 2007
    #7
  8. Eric

    Eric Guest

    Eric wrote:
    > wrote:
    > > > Someone made a similar suggestion, but it seems as if you are
    > > > redefining the sub in the file in which it is being called instead of
    > > > using it from it's current module(?).

    > >
    > > sub{...} creates a new anonymous sub. It can't redefine any existing subs
    > > because to do that, you would need to use the name (or a ref to) an
    > > existing sub, which being anonymous this ones doesn't have.
    > >
    > > Xho

    >
    > Ok - I can see the rationale behind this. In fact, I tried it, and it
    > worked. However, I got the oddest response message I've ever seen:
    >
    > Attempt to free unreferenced scalar: SV 0xafc2db8, Perl interpreter:
    > 0xaa069a0 at <file> <line>
    >
    > (where 'file' and 'line' were removed in the above).
    >
    > I should tell you that I got this message running different code than
    > that which I provided in my posting. So I will need to investigate
    > what else is going on. I will also try it with the code I posted to
    > see if I get the same error. But off hand, does the message indicate
    > anything to you?
    >
    > Eric


    Scratch this one - I think the error was prompted by something else in
    the code.
     
    Eric, May 1, 2007
    #8
  9. Eric

    Guest

    Eric <> wrote:
    > wrote:
    > > > Someone made a similar suggestion, but it seems as if you are
    > > > redefining the sub in the file in which it is being called instead of
    > > > using it from it's current module(?).

    > >
    > > sub{...} creates a new anonymous sub. It can't redefine any existing
    > > subs because to do that, you would need to use the name (or a ref to)
    > > an existing sub, which being anonymous this ones doesn't have.
    > >
    > > Xho

    >
    > Ok - I can see the rationale behind this. In fact, I tried it, and it
    > worked. However, I got the oddest response message I've ever seen:
    >
    > Attempt to free unreferenced scalar: SV 0xafc2db8, Perl interpreter:
    > 0xaa069a0 at <file> <line>


    What version of Perl are you using? I've seen things like that in
    some of the early 5.8.x perls that went away in the some of the later
    ones.

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
     
    , May 1, 2007
    #9
  10. Eric

    Eric Guest

    wrote:
    > Eric <> wrote:
    > > wrote:
    > > > > Someone made a similar suggestion, but it seems as if you are
    > > > > redefining the sub in the file in which it is being called instead of
    > > > > using it from it's current module(?).
    > > >
    > > > sub{...} creates a new anonymous sub. It can't redefine any existing
    > > > subs because to do that, you would need to use the name (or a ref to)
    > > > an existing sub, which being anonymous this ones doesn't have.
    > > >
    > > > Xho

    > >
    > > Ok - I can see the rationale behind this. In fact, I tried it, and it
    > > worked. However, I got the oddest response message I've ever seen:
    > >
    > > Attempt to free unreferenced scalar: SV 0xafc2db8, Perl interpreter:
    > > 0xaa069a0 at <file> <line>

    >
    > What version of Perl are you using? I've seen things like that in
    > some of the early 5.8.x perls that went away in the some of the later
    > ones.
    >
    > Xho


    I'm using:

    $ perl -v

    This is perl, v5.8.0 built for i386-linux-thread-multi
    (with 1 registered patch, see perl -V for more detail)

    Eric
     
    Eric, May 1, 2007
    #10
  11. Eric

    Guest

    Eric <> wrote:
    > wrote:
    > > >
    > > > Attempt to free unreferenced scalar: SV 0xafc2db8, Perl interpreter:
    > > > 0xaa069a0 at <file> <line>

    > >
    > > What version of Perl are you using? I've seen things like that in
    > > some of the early 5.8.x perls that went away in the some of the later
    > > ones.
    > >
    > > Xho

    >
    > I'm using:
    >
    > $ perl -v
    >
    > This is perl, v5.8.0 built for i386-linux-thread-multi
    > (with 1 registered patch, see perl -V for more detail)


    If you want to use threads, you should definitely upgrade. v5.8.0 did
    all kinds of misbehavior under threading.

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
     
    , May 1, 2007
    #11
    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. nus

    object-oriented perl

    nus, Dec 24, 2003, in forum: Perl
    Replies:
    0
    Views:
    519
  2. Replies:
    2
    Views:
    433
    Bruno Desthuilliers
    May 26, 2008
  3. rolo
    Replies:
    3
    Views:
    175
    Robert Klemme
    Apr 9, 2004
  4. Stefan
    Replies:
    4
    Views:
    142
    Mina Naguib
    Sep 16, 2003
  5. Replies:
    2
    Views:
    178
    Brian McCauley
    Dec 22, 2005
Loading...

Share This Page