今天突然想起把自己之前写的一个脚本换成多线程的模式改写一下,因为之前的模式很多时间都阻塞住了,每次批量搞几千个机器太费时。
先是使用老的Thread模块把脚本改写的一遍,都把脚本写好了验证OK才发现这个是老的模块,不推荐使用,肺都气炸了。还好新的threads模块也类似,简单修改了一下也OK,而且新模块的功能强大很多,可靠性也好。测试一下
#!/usr/bin/perl
use strict;
use warnings;
use threads;
my @test=(1...988);
srand();
&muti_work;
sub muti_work(){
my $JOBN=30;
my $jobs=0;
while(@test){
if($jobs<$JOBN && $jobs>=0) {
my $pid=threads->create(\&echon,shift @test);
$jobs++;
} elsif($jobs>=$JOBN) {
my @actlist=threads->list(threads::joinable);
foreach my $t (@actlist) {
$t->join;
$jobs--;
}
sleep 0.1;
}
}
while($jobs>0) {
my @actlist=threads->list(threads::joinable);
foreach my $t(@actlist){
$t->join;
$jobs--;
}
sleep 0.5;
}
}
sub echon(){
my $num=shift;
my $t=int(rand(8));
sleep $t;
my $thr = threads->self();
print "i am working $num sleep $t\n";
threads->exit(0);
}
print "ok\n";
如果涉及到每个线程都有一个返回值的话,可以在函数里面直接运行return就行。使用my $vat=$t->join的形式进行返回值的获取。如果返回的是一个数组,也是可以直接return @list的,但是thread->create的时候需要加参数。详细的看cpan的文档。
my $pid=threads->create({'context' => 'list'},$rfun,@para);