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

Thanks for the example. One question. I've read the threads perldoc. async expects an anonymous subroutine. All of my code is in a module. Is there anyway I can call async with a method? I'm not sure what the syntax would be...
  • Comment on Re^2: Doing two things at once, fork question.

Replies are listed 'Best First'.
Re^3: Doing two things at once, fork question. (Updated!)
by BrowserUk (Patriarch) on Mar 07, 2008 at 22:36 UTC
    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.

      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.