Below is some code being used to test threads. I'm trying to move
some code into separate files and use "do <file>" to run the code.
When I try this, I get strange behaviour. It is likely some isuee of
variable visibility, but I can't figure it out. Help please. (All
results are on Win2K with ithreads).
Regards,
Steve

The code is Q.pl (below).

When it is run as is, it runs fine, producing:
Sleeper 2, iteration 0, error 0.00000, current time 0.00000
Sleeper 3, iteration 0, error 0.00000, current time 0.00000
Sleeper 5, iteration 0, error 0.00000, current time 0.00000
Sleeper 7, iteration 0, error 0.00000, current time 0.00000
Sleeper 11, iteration 0, error 0.00000, current time 0.00000
Sleeper 2, iteration 1, error 0.00313, current time 0.20313
Sleeper 3, iteration 1, error 0.01250, current time 0.31250
Sleeper 2, iteration 2, error 0.00625, current time 0.40625
Sleeper 5, iteration 1, error 0.00000, current time 0.50000
Sleeper 2, iteration 3, error 0.00938, current time 0.60938
Sleeper 3, iteration 2, error 0.00938, current time 0.60938
Sleeper 7, iteration 1, error 0.00313, current time 0.70313
Sleeper 2, iteration 4, error 0.01251, current time 0.81251
Sleeper 3, iteration 3, error 0.00626, current time 0.90626
Sleeper 5, iteration 2, error 0.00001, current time 1.00001
Sleeper 2, iteration 5, error 0.00001, current time 1.00001
Sleeper 11, iteration 1, error 0.00938, current time 1.10938
Sleeper 2, iteration 6, error 0.00313, current time 1.20313
Sleeper 3, iteration 4, error 0.00313, current time 1.20313
Sleeper 7, iteration 2, error 0.00626, current time 1.40626
Sleeper 2, iteration 7, error 0.00626, current time 1.40626
Sleeper 5, iteration 3, error 0.00001, current time 1.50001
Sleeper 3, iteration 5, error 0.00001, current time 1.50001
Sleeper 2, iteration 8, error 0.00939, current time 1.60939
Sleeper 3, iteration 6, error 0.01251, current time 1.81251
Sleeper 2, iteration 9, error 0.01251, current time 1.81251
Sleeper 5, iteration 4, error 0.00001, current time 2.00001
Sleeper 2, iteration 10, error 0.00001, current time 2.00001

If you comment out the Q1 and Q2 sections, and use the "do" file
commands to run the same code (now located in Q1.pl and Q2.pl), the
program produces the same (correct) output except it also prints (when
exiting):
Attempt to free unreferenced scalar during global destruction.
Scalars leaked: 1
Scalars leaked: 1
Scalars leaked: 1
Scalars leaked: 1
Scalars leaked: 1

If only one of the "do" file commands is used (and the other left as
explict code) then there are complaints about initialization, e.g. if
Q1 is left inline, but Q2 is done as a "do 'Q2.pl';", it produces:
Sleeper 2, iteration 0, error 0.00000, current time 0.00000
Sleeper 3, iteration 0, error 0.00000, current time 0.00000
Sleeper 5, iteration 0, error 0.00000, current time 0.00000
Sleeper 7, iteration 0, error 0.00000, current time 0.00000
Sleeper 11, iteration 0, error 0.00000, current time 0.00000
Use of uninitialized value in numeric eq (==) at C:/Program
Files/Perl/lib/threads.pm line 71.
Use of uninitialized value in numeric eq (==) at C:/Program
Files/Perl/lib/threads.pm line 71.
Use of uninitialized value in numeric eq (==) at C:/Program
Files/Perl/lib/threads.pm line 71.
Use of uninitialized value in numeric eq (==) at C:/Program
Files/Perl/lib/threads.pm line 71.
Use of uninitialized value in numeric eq (==) at C:/Program
Files/Perl/lib/threads.pm line 71.
A thread exited while 6 other threads were still running.

============= Code for Q.pl
use strict ;
use warnings;

use Time::HiRes qw(gettimeofday) ;
use threads ;

sub delay ($) { select ( undef, undef, undef, $_[0] ) } ;

sub Timer {
my ( $timeout ) = _ ;
my $basetime = gettimeofday ;
for my $c ( 0 .. 10/$timeout ) {
my $current = gettimeofday - $basetime ;
my $error = $current - $c*$timeout/10 ;
printf
"Sleeper %3d, iteration %3d, error %2.5f, current time
%4.5f\n" ,
$timeout, $c, $error, $current ;
my $sleep = ($c+1)*$timeout/10 - gettimeofday + $basetime ;
delay $sleep ;
} ;
}

my %threads ;

#
do 'Q1.pl' ;

# Q1.pl contains this, and only this:
# foreach my $timeout ( 2, 3, 5, 7, 11 ) {
# my $t = threads->new( \&Timer, $timeout );
# # Can't store a thread object directly into Client_Data,
# #so just store the thread ID
# $threads{$timeout} = $t->tid ;
# }


#
# do 'Q2.pl' ;

# Q2.pl contains this, and only this
foreach my $timeout ( 2, 3, 5, 7, 11 ) {
threads->object($threads{$timeout})->join ;
}
__END__