我在'./photo‘目录中有一些JPG文件,我使用Image::thumbnails和GD来创建它们的缩略图。
code1.pl:
use Image::Thumbnail;
my $dir = './photos' ;
opendir(DIR, $dir) or die "Can not open dir\n";
my @files = grep { /\.JPG/ && -f "$dir/$_" ; } readdir( DIR );
closedir DIR;
my $t1 = time;
for my $f (@files){
print $f, "\n";
my $t = new Image::Thumbnail(
module => 'GD',
size => 200,
create => 1,
input => $dir . '/' . $f,
outputpath => $dir . '/' . 'thumb_' . $f,
);
}
print "Time used: ", time-$t1, "\n";我测试了9张照片,每个大小约为4m,code1.pl总共运行了9~10s。
code2.pl:(使用mojo::IOLoop,实际上我想在mojo web app中处理客户端上传的照片)
use Image::Thumbnail;
use Mojo::Base -strict;
use Mojo::IOLoop;
my $dir = './photos' ;
opendir(DIR, $dir) or die "Can not open dir\n";
my @files = grep { /\.JPG/ && -f "$dir/$_" ; } readdir( DIR );
closedir DIR;
my $t1 = time;
my $loop = Mojo::IOLoop->singleton;
$loop->recurring(
0 => sub {
$loop->stop and return unless my $f = shift @files;
print $f, "\n";
my $t = new Image::Thumbnail(
module => 'GD',
size => 200,
create => 1,
input => $dir . '/' . $f,
outputpath => $dir . '/' . 'thumb_' . $f,
);
}
);
$loop->on(finish => sub {
print "Time used: ", time-$t1, "\n";
});
$loop->start;这个code2.pl可以正确运行,但消耗的时间似乎没有变化。
code3.pl:(我将循环更改为子进程)
use Image::Thumbnail;
use Mojo::Base -strict;
use Mojo::IOLoop;
my $dir = './photos' ;
opendir(DIR, $dir) or die "Can not open dir\n";
my @files = grep { /\.JPG/ && -f "$dir/$_" ; } readdir( DIR );
closedir DIR;
my $t1 = time;
my $loop = Mojo::IOLoop->singleton;
$loop->subprocess(
map{
sub {
#$loop->stop and return unless my $f = shift @files;
my $f = $_ ;
my $t = new Image::Thumbnail(
module => 'GD',
size => 200,
create => 1,
input => $dir . '/' . $f,
outputpath => $dir . '/t_' . $f,
);
print $f, "\n";
}
} @files
);
$loop->on(finish => sub {
print "Time used: ", time-$t1, "\n";
});
$loop->start;code3.pl提升错误:
Subprocesses do not support fork emulation at C:/Perl/site/lib/Mojo/IOLoop.pm line 152.
shell returned 255我在winXP (5.20.2版)上使用了activeperl,期待您的帮助。
发布于 2018-02-11 22:09:31
首先,在您的第三个示例中,Mojo::IOLoop::Subprocess的使用不正确。documentation指出,需要为run方法提供两个子例程,第一个子例程将在“后台”执行,并应返回结果值(如果有),该值将由第二个子例程处理。在本例中,您应该为@files中的每个元素创建新的子流程对象。
相对于code3.pl返回的错误,看起来Mojo::IOLoop或者至少您的版本不能在使用d_pseudofork标志编译的code3.pl上工作。考虑在WinXP上使用Strawberry Perl,因为它是开放源码的发行版,并且针对Windows进行了更好的优化。
https://stackoverflow.com/questions/48212137
复制相似问题