首先,对代码本身进行一些评论。您需要确保您拥有:
use strict;
use warnings;
在。。。之初every脚本。第二:
@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";
}
}
Output:
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";
}
}
Output:
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'