Why "scalars leaked" in ithread? Is my code right for doing this?

N

niry

Why "scalars leaked" output occurs?
My purpose is let three threads all run to the line commented at the
same time(of course, almost the same time).
And is there any better ways to do that?

---output:---

1 Before: 47
2 Before: 47
3 Before: 47
3: 47(0)
1: 47(3)
2: 47(2)
Scalars leaked: 2 #???
Scalars leaked: 2 #???
Scalars leaked: 2 #???


---code:----
use threads qw(yield);
use Thread::Semaphore;
use Time::localtime;

my $semaphore = new Thread::Semaphore;
my $GlobalVariable : shared = 3;
$thr1 = new threads \&sample_sub, 1;
$thr2 = new threads \&sample_sub, 2;
$thr3 = new threads \&sample_sub, 3;
sub sample_sub {
my $SubNumber = shift @_;
$semaphore->down;
$GlobalVariable--;
$semaphore->up;
my $t=0;
$now = localtime();
print "$SubNumber Before:\t".$now->sec."\n";
while ($GlobalVariable>0) {yield;$t++;}
$now = localtime();
print "$SubNumber:\t".$now->sec."($t)\n";
################ all three threads run to here at the same time
}
$thr1->join;
$thr2->join;
$thr3->join;
 
B

Bob Walton

niry said:
Why "scalars leaked" output occurs?
My purpose is let three threads all run to the line commented at the
same time(of course, almost the same time).
And is there any better ways to do that?

---output:---

1 Before: 47
2 Before: 47
3 Before: 47
3: 47(0)
1: 47(3)
2: 47(2)
Scalars leaked: 2 #???
Scalars leaked: 2 #???
Scalars leaked: 2 #???


---code:----
use threads qw(yield);
use Thread::Semaphore;
use Time::localtime;

my $semaphore = new Thread::Semaphore;
my $GlobalVariable : shared = 3;
$thr1 = new threads \&sample_sub, 1;
$thr2 = new threads \&sample_sub, 2;
$thr3 = new threads \&sample_sub, 3;
sub sample_sub {
my $SubNumber = shift @_;
$semaphore->down;
$GlobalVariable--;
$semaphore->up;
my $t=0;
$now = localtime();
print "$SubNumber Before:\t".$now->sec."\n";
while ($GlobalVariable>0) {yield;$t++;}
$now = localtime();
print "$SubNumber:\t".$now->sec."($t)\n";
################ all three threads run to here at the same time
}
$thr1->join;
$thr2->join;
$thr3->join;

The problem appears to be in Time::localtime. If you eliminate it
(commenting out $now=... and replacing $now->sec with (localtime)[0] ),
the leaked scalar messages don't occur.

BTW, although it isn't related to your problem, you should

use strict;

and ensure your sub's are not using package globals, especially when
they are in threads (you forgot my $now;).
 
N

niry

Bob Walton said:
niry said:
Why "scalars leaked" output occurs?
My purpose is let three threads all run to the line commented at the
same time(of course, almost the same time).
And is there any better ways to do that?

---output:---

1 Before: 47
2 Before: 47
3 Before: 47
3: 47(0)
1: 47(3)
2: 47(2)
Scalars leaked: 2 #???
Scalars leaked: 2 #???
Scalars leaked: 2 #???


---code:----
use threads qw(yield);
use Thread::Semaphore;
use Time::localtime;

my $semaphore = new Thread::Semaphore;
my $GlobalVariable : shared = 3;
$thr1 = new threads \&sample_sub, 1;
$thr2 = new threads \&sample_sub, 2;
$thr3 = new threads \&sample_sub, 3;
sub sample_sub {
my $SubNumber = shift @_;
$semaphore->down;
$GlobalVariable--;
$semaphore->up;
my $t=0;
$now = localtime();
print "$SubNumber Before:\t".$now->sec."\n";
while ($GlobalVariable>0) {yield;$t++;}
$now = localtime();
print "$SubNumber:\t".$now->sec."($t)\n";
################ all three threads run to here at the same time
}
$thr1->join;
$thr2->join;
$thr3->join;

The problem appears to be in Time::localtime. If you eliminate it
(commenting out $now=... and replacing $now->sec with (localtime)[0] ),
the leaked scalar messages don't occur.

BTW, although it isn't related to your problem, you should

use strict;

and ensure your sub's are not using package globals, especially when
they are in threads (you forgot my $now;).

I added "use strict;" just as you said, but many errors occured.
something like follow:
---
Global symbol "$thr3" requires explicit package name at
D:\perlworks\t.pl line 11.
---
the (localtime)[0] didnot give me the output I wanted, but "
Time::tm=ARRAY(0x192d528)"
and "scalars leaked" still there.
why? I am using "ActivePerl Build 806"
thanks!
 
N

niry

sorry, my mistake
but I did as you said, still "scalars leaked" exists
and time-output is not sec any more, but something like"Time::tm=ARRAY(0x19f4870)"
---code---
use threads qw(yield);
use Thread::Semaphore;
use Time::localtime;
use strict;

package main;

my $semaphore = new Thread::Semaphore 1;

my $GlobalVariable : shared = 3;
my $thr1 = new threads \&sample_sub, 1;
my $thr2 = new threads \&sample_sub, 2;
my $thr3 = new threads \&sample_sub, 3;
$thr1->join;
$thr2->join;
$thr3->join;

print "-----------------------------------\n";

sub sample_sub {
my $SubNumber = shift @_;
$semaphore->down;
$GlobalVariable--;
$semaphore->up;
my $t=0;
print "$SubNumber Before:\t".(localtime)[0]."\n";
while ($GlobalVariable>0) {yield;$t++;}
print "$SubNumber:\t".(localtime)[0]."($t)\n";
}
 
B

Bob Walton

niry said:
sorry, my mistake
but I did as you said, still "scalars leaked" exists
and time-output is not sec any more, but something like"Time::tm=ARRAY(0x19f4870)"
---code---
use threads qw(yield);
use Thread::Semaphore;
use Time::localtime;


Get rid of the use Time::localtime; above -- you are still using
Time::localtime's localtime function, which is vastly different from the
builtin localtime function. I checked -- in your code with that line
commented out, you don't get leaked scalar messages, and the results of
localtime are as expected.

As to why the Time::localtime module leaks scalars, I have no clue. It
uses some other modules, like Class::Struct, so the problem might be in
one of them.

use strict;

package main;

my $semaphore = new Thread::Semaphore 1;

my $GlobalVariable : shared = 3;
my $thr1 = new threads \&sample_sub, 1;
my $thr2 = new threads \&sample_sub, 2;
my $thr3 = new threads \&sample_sub, 3;
$thr1->join;
$thr2->join;
$thr3->join;

print "-----------------------------------\n";

sub sample_sub {
my $SubNumber = shift @_;
$semaphore->down;
$GlobalVariable--;
$semaphore->up;
my $t=0;
print "$SubNumber Before:\t".(localtime)[0]."\n";
while ($GlobalVariable>0) {yield;$t++;}
print "$SubNumber:\t".(localtime)[0]."($t)\n";
}
 
N

niry

Problems solved with your instruction.
Really thanks to you!!

And it's my first time to know the conception of "build-in function".
I am new to perl:)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top