Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Perl threads

by Superfox il Volpone (Sexton)
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

Replies are listed 'Best First'.
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 (Deacon) 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!
Re: Perl threads
by Superfox il Volpone (Sexton) on Jan 17, 2014 at 23:25 UTC
    uh, got confused by the function ampersand &, I thought it was a reference :)

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?
[Corion]: Cosmic37: Basically, you read one file into a hash, keyed by your key, and then match the lines from the second file to that hash
[Cosmic37]: note that the two files only have datetimes which may match whereas other data per line is different format in file1 and file2 - is that really intersection?
[jedikaiti]: Hi Monks
[Corion]: Cosmic37: Well, if you want to use only parts of a line for the key, see split or whatever other mechanism to extract the key from the line
[Corion]: Hi jedikaiti!
[Cosmic37]: is there a webpage for full CB for this chat rather than side panel chat?
[Cosmic37]: thank you for advice
[Cosmic37]: peach greets jedi
[Cosmic37]: ok this one works better fullpage chat
[Cosmic37]: test

How do I use this? | Other CB clients
Other Users?
Others perusing the Monastery: (9)
As of 2017-06-29 16:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    How many monitors do you use while coding?















    Results (672 votes). Check out past polls.