了解 Mojo::IOLoop 循环和子流程
understanding Mojo::IOLoop recurring and subprocess
我在“./photo”目录中有一些 JPG 文件,我使用 Image::Thumbnail 和 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~10秒
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上使用activeperl,(v5.20.2),期待您的帮助。
首先,Mojo::IOLoop::Subprocess
在您的第三个示例中使用不正确。 documentation 声明 run
方法需要 2 个子例程,第一个是将在 "background" 中执行的子例程,并且应该 return 结果值(如果有的话)将是由第二个子程序处理。在您的情况下,您应该为 @files
.
中的每个元素创建新的子流程对象
相对于错误 code3.pl
returns,它看起来像 Mojo::IOLoop
或者至少你的版本不能在使用 d_pseudofork
标志编译的 Perl 上运行。考虑在 WinXP 上使用 Strawberry Perl,因为它是开源发行版并且针对 Windows 进行了更好的优化。
我在“./photo”目录中有一些 JPG 文件,我使用 Image::Thumbnail 和 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~10秒
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上使用activeperl,(v5.20.2),期待您的帮助。
首先,Mojo::IOLoop::Subprocess
在您的第三个示例中使用不正确。 documentation 声明 run
方法需要 2 个子例程,第一个是将在 "background" 中执行的子例程,并且应该 return 结果值(如果有的话)将是由第二个子程序处理。在您的情况下,您应该为 @files
.
相对于错误 code3.pl
returns,它看起来像 Mojo::IOLoop
或者至少你的版本不能在使用 d_pseudofork
标志编译的 Perl 上运行。考虑在 WinXP 上使用 Strawberry Perl,因为它是开源发行版并且针对 Windows 进行了更好的优化。