I have a trouble with the following very simple and small Perl script on Windows platform.
use strict;
use warnings;
use threads;
use threads::shared;
my $print_mut : shared;
my $run_mut : shared;
my $counter : shared;
$counter = 30;
###############################################################
sub _print($)
{
lock($print_mut);
my $str = shift;
my $id = threads->tid();
print "[Thread_$id] $str";
return;
}
###############################################################
sub _get_number()
{
lock($counter);
return $counter--;
}
###############################################################
sub _get_cmd($)
{
my $i = shift;
if ($^O eq 'MSWin32')
{
return qq{cmd /c "echo $i"};
}
return "echo $i";
}
###############################################################
sub thread_func()
{
while ((my $i = _get_number()) > 0)
{
my $str = 'NONE';
{
lock($run_mut);
my $cmd = _get_cmd($i);
$str = `$cmd`;
}
chomp $str;
_print "Got string: '$str'.\n";
}
return;
}
###############################################################
# Start all threads
my @threads;
for (1 .. 8)
{
my $thr = threads->create('thread_func');
push @threads, $thr;
}
# Wait for completion of the threads
foreach (@threads)
{
$_->join;
}
###############################################################
On my Linux box (Perl v5.10.0) I get correct (expected) results:
$ perl ~/tmp/thr2.pl [Thread_1] Got string: '30'. [Thread_1] Got string: '29'. [Thread_2] Got string: '28'. [Thread_1] Got string: '27'. [Thread_2] Got string: '26'. [Thread_1] Got string: '25'. [Thread_1] Got string: '23'. [Thread_2] Got string: '24'. [Thread_2] Got string: '20'. [Thread_2] Got string: '19'. [Thread_1] Got string: '22'. [Thread_4] Got string: '18'. [Thread_5] Got string: '15'. [Thread_2] Got string: '17'. [Thread_2] Got string: '12'. [Thread_3] Got string: '21'. [Thread_4] Got string: '14'. [Thread_4] Got string: '7'. [Thread_1] Got string: '16'. [Thread_6] Got string: '11'. [Thread_2] Got string: '10'. [Thread_2] Got string: '2'. [Thread_3] Got string: '8'. [Thread_5] Got string: '13'. [Thread_8] Got string: '6'. [Thread_4] Got string: '5'. [Thread_1] Got string: '4'. [Thread_6] Got string: '3'. [Thread_7] Got string: '9'. [Thread_2] Got string: '1'. $
However, on Windows (Perl v5.10.1) I get a mess:
C:\>perl Z:\tmp\thr2.pl [Thread_1] Got string: '30'. [Thread_2] Got string: '29'. [Thread_2] Got string: '21'. [Thread_6] Got string: '26'. [Thread_5] Got string: '25'. [Thread_5] Got string: '17'. [Thread_8] Got string: '23'. [Thread_1] Got string: '22'. [Thread_1] Got string: '14'. [Thread_2] Got string: '20'. [Thread_6] Got string: '18'. [Thread_7] Got string: '24'. [Thread_7] Got string: '9'. [Thread_8] Got string: '15'. [Thread_3] Got string: '28'. [Thread_3] Got string: '6'. [Thread_4] Got string: '12'. [Thread_2] Got string: '[Thread_4] Got string: '27'. 19'. [Thread_6] Got string: '10'. [Thread_5] Got string: '16'. [Thread_7] Got string: '8'. [Thread_8] Got string: '7'. [Thread_1] Got string: '13'. [Thread_3] Got string: '5'. [Thread_4] Got string: '4'. [Thread_2] Got string: '11'. [Thread_6] Got string: '[Thread_2] Got string: '3'. [Thread_5] Got string: '2'. 1'. C:\>
The problem happens when I run a command (doesn't matter what command) from the thread function via backtick to collect it's output.
I have very limited experience with threads in Perl and with Perl on Windows. I always tried to avoid using threads in Perl at all, but this time I have to use them.
I didn't manage to find the answer in perldoc and Google. Could someone please explain what's wrong with my script?
Thanks in advance!