in reply to Re^2: Doing two things at once, fork question.
in thread Doing two things at once, fork question.

Is there anyway I can call async with a method? I'm not sure what the syntax would be...

Yes. (Update: Corrected method syntax)

# normal sub - no parameters. my $thread = async \&subname; # sub with args my $thread = async \&subname, $arg1, $arg2; # method - no parameters. my $thread = async \&pClass::method, $obj; # method with args my $thread = async \&Classname::method, $obj, $arg1, $arg2;

And note that async is just a functional alias for

my $thread = threads->create( \&sub, $arg1, $arg2 ); my $thread = threads->new( \&Classname::method, $obj, $arg1, $arg2 );

But note. Calling objects (object methods) across threads probably won't work in most cases.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
"Too many [] have been sedated by an oppressive environment of political correctness and risk aversion."

Replies are listed 'Best First'.
Re^4: Doing two things at once, fork question. (thread + method)
by tye (Sage) on Mar 07, 2008 at 23:25 UTC

    How I would use a method:

    my $thread= async( sub { $obj->method( ... ) } );

    If one has some aversion to that technique for some reason, it is likely better to use the following hack rather some of those suggested in the above node:

    my $thread= async( $obj->can("method"), $obj, ... );

    - tye        

      My adversion to your first method is that it doesn't work:

      use threads;; { package junk; sub new{bless [], $_[0] } sub method{ printf __PACKAGE__ . ": @_" } } $o = junk->new;; async{ sub{ $o->method( qw[ the quick brown fox ] ) } };; ## No output! async \&junk::method, $o, qw[ the quick brown fox ];; #outputs junk: junk=ARRAY(0x1adcdec) the quick brown fox

      Likewise your second:

      ... setup as above async( $obj->can("method"), $obj, qw[ the quick brown fox ] );; [Type of arg 1 to threads::async must be block or sub {} (not subrouti +ne entry) at ...

      Either of these do:

      async sub{ $o->method( qw[ the quick brown fox ] ) };; junk: junk=ARRAY(0x1b7d5a4) the quick brown fox async{ $o->method( qw[ the quick brown fox ] ) };; junk: junk=ARRAY(0x1c1b4a4) the quick brown fox

      But I'm not sure that there is any benefit to the extra level of indirection.

      In particular, I'm still unsure how usable objects across threads are. They now work for (some) simple cases where they did not in the early days, but I'm still uncertain that they will work properly for all cases. If the object is closed over as in most of the cases above, things seem to function because the object is subject to cloning.

      But if you want to pass an object to a thread, where the object was created after the thread was spawned, or even the class was loaded after the thread was spawned, I think you're in for some surprises.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

        The ->can case is just Perl's broken (or at least picky and somewhat perverse) prototypes so you can work around it easily enough with:

        &async( $o->can("method"), $o, ... );

        Note the leading ampersand. Though I wouldn't recommend this hack even if the ambersand wasn't required.

        The other problem was error(s) on your part.

        async{ sub{ $o->method­( qw[ the quick brown fox ] ) } };;

        Note that you used a curly brace not a paren. After fixing that I still occasionally didn't get output so I added a sleep in the main thread.

        I certainly wasn't trying to make the case that using objects in Perl threads were worthwhile, obviously.

        But I'm not sure that there is any benefit to the extra level of indirection.

        I consider "not hard-coding method selection" a fine benefit, especially since what class a method actually comes from is an implementation detail that the user of the object shouldn't be bothered with much less be relying upon. Then there is the possiblity of an object that is aware of "method" context and so breaks with your hack.

        Adding a simple pair of braces (with or without "sub", depending on your paren choices and the vagaries of Perl prototypes) to a normal method invocation seems a much better idea than hard-coding a method selection and then listing the object after that. The benefit on clarity of code (even if the code mostly doesn't work because Perl threads still rather suck) is quite significant.

        - tye