Прежде всего, несколько комментариев к самому коду. Вы должны убедиться, что у вас есть:
use strict;
use warnings;
в начале каждого сценария. Во-вторых:
@file_list = @ARGV; #Our file list
$nofiles = $#file_list + 1; #Real number of files
не требуется, так как массив в скалярном контексте оценивается числом элементов в массиве. То есть:
$nofiles = @ARGV;
правильно даст вам количество файлов в @ARGV
независимо от значения $[
.
Наконец, сценарий можно значительно упростить, разделив список файлов перед запуском потоков:
use strict; use warnings;
use threads;
use threads::shared;
my @threads = (
threads->new(\&process, @ARGV[0 .. @ARGV/2]),
threads->new(\&process, @ARGV[@ARGV/2 + 1 .. @ARGV - 1]),
);
$_->join for @threads;
sub process {
my @files = @_;
warn "called with @files\n";
for my $file ( @files ) {
warn "opening '$file'\n";
sleep rand 3;
warn "closing '$file'\n";
}
}
Выход:
C:\Temp> thr 1 2 3 4 5
called with 1 2 3
opening '1'
called with 4 5
opening '4'
closing '4'
opening '5'
closing '1'
opening '2'
closing '5'
closing '2'
opening '3'
closing '3'
В качестве альтернативы, вы можете позволить потокам переходить к следующей задаче по мере их выполнения:
use strict; use warnings;
use threads;
use threads::shared;
my $current :shared;
$current = 0;
my @threads = map { threads->new(\&process, $_) } 1 .. 2;
$_->join for @threads;
sub process {
my ($thr) = @_;
warn "thread $thr stared\n";
while ( 1 ) {
my $file;
{
lock $current;
return unless $current < @ARGV;
$file = $ARGV[$current];
++ $current;
}
warn "$thr: opening '$file'\n";
sleep rand 5;
warn "$thr: closing '$file'\n";
}
}
Выход:
C:\Temp> thr 1 2 3 4 5
thread 1 stared
1: opening '1'
1: closing '1'
1: opening '2'
thread 2 stared
2: opening '3'
2: closing '3'
2: opening '4'
1: closing '2'
1: opening '5'
1: closing '5'
2: closing '4'