Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

threads and leaking scalars

by deliria (Chaplain)
on Aug 03, 2003 at 23:24 UTC ( [id://280529]=perlquestion: print w/replies, xml ) Need Help??

deliria has asked for the wisdom of the Perl Monks concerning the following question:

I started playing around with threads in perl5.8 and came across something I can't seem to get my head around.

In the following piece of code I call 'new My_mod( \%config )'. I figured this would work, however Perl complains about 1 leaked scalar for each of the threads started. If I don't pass it an argument it does not leak scalars.

I figured 5.8.1 might do better, so i compiled perl-5.8.1rc4 and had it run the example, but the problem remained.

It's fairly easy to work around this problem, but i'd like to understand why it leaks scalars, or where i'm doing something wrong.

#!/usr/local/bin/perl package My_mod; use warnings; use strict; use threads; use threads::shared; our $thread_abort : shared = 0; our $thread_continue : shared = 0; sub new { my ( $pkg,$config ) = @_; for ( 0..4 ) { threads->new( \&test_t ); } bless { }, $pkg; } sub test_t { my $iter = 0; while ( 1 ) { threads->yield; last if $thread_abort; next unless $thread_continue; ++$iter; } print "My iter count : $iter\n"; } sub activate { my $pkg = shift; $thread_continue = 1; } sub abort { my $pkg = shift; $thread_abort = 1; for my $thr ( threads->list ) { if ( $thr->tid && !($thr == threads->self ) ) { $thr->join } } } package main; my %config = ( 'test' => '3' ); my $node = new My_mod( \%config ); $node->activate; sleep(10); $node->abort;
Any thoughts?

Replies are listed 'Best First'.
Re: threads and leaking scalars
by liz (Monsignor) on Aug 04, 2003 at 08:03 UTC
    I've been trying a lot to find answers to these leaked scalar messages related to threads. I've given up. Life's too short. You shouldn't be getting them if your using "normal" (as in: non-XS) code, so you should consider them to be a bug in the threads::shared module.

    However, I see you're using threads->yield(). In general I would say: don't. From the documentation:

    threads->yield();
       This is a suggestion to the OS to let this thread
       yield CPU time to other threads.  What actually hap-
       pens is highly dependent upon the underlying thread
       implementation.
    
    Furthermore from perlthrtut:

    It is important to remember that yield() is only a hint to give up the CPU, it depends on your hardware, OS and threading libraries what actually happens. Therefore it is important to note that one should not build the scheduling of the threads around yield() calls. It might work on your platform but it won't work on another platform.

    In my experience, under Linux yield() does nothing. So you're effectively burning all of your CPU in this loop:

    while ( 1 ) { threads->yield; last if $thread_abort; next unless $thread_continue; ++$iter; }
    I suggest you look at what you can do with lock(), cond_wait() and cond_signal() from threads::shared.

    Hope this helps.

    Liz

    Update: added stuff about perlthrtut, which I guess should be in big, bold, red letters in the tutorial ;-)

      Well, at least I'm not doing anything wrong with passing the argument (: .. (i guess).

      Based on perlthrtut I got the impression threads->yield() was the way to go. I started using this function because a Bench i wrote gave me a 20% better performance, but on closer reflection my Benchmark was set up wrong.

      Thx, i'll have a look-see again at threads::shared

Re: threads and leaking scalars
by ikegami (Patriarch) on Mar 21, 2008 at 01:13 UTC
    Whatever the bug was, it seems to have been fixed.
    >c:\progs\perl580\bin\perl 280529.pl My iter count : 511379 My iter count : 511379 My iter count : 511381 Scalars leaked: 1 My iter count : 511381 Scalars leaked: 1 My iter count : 511381 Scalars leaked: 1 Scalars leaked: 1 Scalars leaked: 1 >c:\progs\perl588\bin\perl 280529.pl My iter count : 614654 My iter count : 614653 My iter count : 614655 My iter count : 614655 My iter count : 614655
Re: threads and leaking scalars (Scalars leaked: 1)
by dpmott (Scribe) on Feb 26, 2004 at 18:09 UTC
    I had this very same problem, and I finally figured it out.
    If you change this line (in new()):
    my ( $pkg,$config ) = @_;
    To this:
    my $pkg = shift; my $config = shift;
    then it will work.

    I suspect that there's too much magic associated with the @_ variable to let threads play nicely with it. So, my recommendation is to *not* use @_ in the same scope as you launch new threads.

    Update:
    Unfortunately, including other modules (say, XML::DOM) may cause this same problem, so you'd have to launch all of your threads before bringing in such modules. This might be a good use for Thread::Pool...

      So, my recommendation is to *not* use @_ in the same scope as you launch new threads.

      shift (in a sub) and shift(@_) result in exactly the same code, so you are still using @_.

      >perl -MO=Concise,x -e"sub x { shift } main::x: 5 <1> leavesub[1 ref] K/REFC,1 ->(end) - <@> lineseq KP ->5 1 <;> nextstate(main 1 -e:1) v ->2 4 <1> shift sK/1 ->5 3 <1> rv2av[t2] sKRM/1 ->4 2 <#> gv[*_] s ->3 -e syntax OK >perl -MO=Concise,x -e"sub x { shift(@_) } main::x: 5 <1> leavesub[1 ref] K/REFC,1 ->(end) - <@> lineseq KP ->5 1 <;> nextstate(main 1 -e:1) v ->2 4 <1> shift sK/1 ->5 3 <1> rv2av[t2] lKRM/1 ->4 2 <#> gv[*_] s ->3
      dpmott, If you are still here--THANK YOU! This has to be one of the nastiest perl warnings to track down. You have saved me many more days of frustration.
Re: threads and leaking scalars
by Monkomatic (Sexton) on Mar 08, 2011 at 00:47 UTC

    Just found this. apparently was a bug fixed in version 5.12.

    They even used your fix @_=() :)

    http://rt.perl.org/rt3/Public/Bug/Display.html?id=70602

Re: threads and leaking scalars
by Monkomatic (Sexton) on Mar 08, 2011 at 00:37 UTC

    Except im getting the same thing in perl 5.10.

    Argg. Problem for tomorrow morning. I found this nasty little gem after finally getting everything fixed and working.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://280529]
Approved by fglock
Front-paged by broquaint
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chanting in the Monastery: (4)
As of 2024-03-28 21:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found