Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Perl threads

by Superfox il Volpone (Acolyte)
on Jan 17, 2014 at 23:19 UTC ( #1071032=perlquestion: print w/ replies, xml ) Need Help??
Superfox il Volpone has asked for the wisdom of the Perl Monks concerning the following question:

Hi there,

I am following the tutorial of perl threads (perlthrtut). However I am not able to run them concurrently. When I create a thread, the control jumps in the function, execute it sequentially and then it returns. For instance, this program:
use strict; use warnings; use Config; use threads; use threads::shared; print("Config{useithreads} : " . $Config{"useithreads"} . "\n"); print("main starting\n"); my $t1 = threads->create(&__logger); my $t2 = threads->create(&__logger); $t1->join(); $t2->join(); print("main done\n"); sub __logger{ #threads->detach(); # raise the error "already detached" print("logger init\n"); sleep(10); print("logger closed\n"); }
prints this code:
Config{useithreads} : define main starting logger init logger closed logger init Thread 1 terminated abnormally: Undefined subroutine &main::1 called a +t ./test_threads.pl line 19. logger closed Thread 2 terminated abnormally: Undefined subroutine &main::1 called a +t ./test_threads.pl line 20. main done
perl -v:
This is perl 5, version 16, subversion 3 (v5.16.3) built for x86_64-li +nux-thread-multi
I can even replace the first function with a while(1){ }, it won`t execute anything else. What am I missing?

Thanks in advance
Kind regards,
s.fox

Comment on Perl threads
Select or Download Code
Re: Perl threads
by Superfox il Volpone (Acolyte) on Jan 17, 2014 at 23:25 UTC
    uh, got confused by the function ampersand &, I thought it was a reference :)
Re: Perl threads
by Lennotoecom (Pilgrim) on Jan 18, 2014 at 00:28 UTC
    \&__logger
    use threads; use threads::shared; $t1 = threads->create(\&__logger, '1'); $t2 = threads->create(\&__logger, '2'); $t1->join(); $t2->join(); print "the end\n"; sub __logger{ $id = shift; print "thread $id init\n"; $time = int(rand(10)); print "thread $id sleeping for $time\n"; sleep($time); print "thread $id ended\n"; }
Re: Perl threads
by Preceptor (Chaplain) on Jan 18, 2014 at 10:48 UTC

    OK, first off:

    &__logger

    Is probably not what you want to be doing. The ampersand denotes a function call, but does so in such a way as to avoid prototypes. I would imagine that's not what you want to do.\ (Functionally it's the same as:)

    __logger(@_);

    The reason your thing is erroring, is that it's running __logger() _before_ starting the threads. And using the return code from '__logger()' to figure out which thread to run:

    use strict; use warnings; use Config; use threads; use threads::shared; print("Config{useithreads} : " . $Config{"useithreads"} . "\n"); print("main starting\n"); my $t1 = threads->create(&__logger); my $t2 = threads->create(&__logger); $t1->join(); $t2->join(); sleep 12; print("main done\n"); sub __logger { #threads->detach(); # raise the error "already detached" print(threads -> self -> tid(). ":logger init\n"); sleep(10); print(threads -> self -> tid(). ":logger closed\n"); return "fish"; }

    Change the last line of logger to 'return "fish"' and you get the same error, with a different name, which illustrates perhaps a little more clearly what's going on - that return code _should_ be irrelevant, but threads -> create is evaluating the function call first. (And spawning an name like that is generally speaking a Bad Thing)

    This is also of course, why your 'detach' isn't working - that sub isn't being run as a thread in the first place.

    What you need to be doing is passing a 'code reference' into 'threads->create'. This should do what you expect:

    use strict; use warnings; use Config; use threads; use threads::shared; print("Config{useithreads} : " . $Config{"useithreads"} . "\n"); print("main starting\n"); my $t1 = threads->create(\&__logger); my $t2 = threads->create(\&__logger); $t1->join(); $t2->join(); print("main done\n"); sub __logger { #threads->detach(); # raise the error "already detached" print(threads -> self -> tid(). ":logger init\n"); sleep(10); print(threads -> self -> tid(). ":logger closed\n"); }

    Putting the 'detach' back in works, but once you detach you can't join - and your program will create and then exit with threads still running. I'd suggest you don't usually want to do that, but if you really do, comment out the 'join' lines, and add a 'sleep 12' instead.

      Hi there, thank you for the solutions!

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1071032]
Approved by boftx
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (13)
As of 2014-11-24 07:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My preferred Perl binaries come from:














    Results (137 votes), past polls