理解Mojo :: IOLoop重复和子进程

时间:2018-01-11 16:49:58

标签: perl mojolicious

我在' ./ 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网络应用中上传的照片)

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),期待你的帮助。

1 个答案:

答案 0 :(得分:1)

首先,在您的第三个示例中,Mojo::IOLoop::Subprocess使用不正确。 documentation表示run方法需要给出2个子程序,首先是将在" background"中执行的子程序。并应返回将由第二个子例程处理的结果值(如果有)。在您的情况下,您应该为@files中的每个元素创建新的子进程对象。

相对错误code3.pl返回,它看起来像Mojo::IOLoop或者至少你的版本不适用于使用d_pseudofork标志编译的Perl。考虑在WinXP上使用Strawberry Perl,因为它是开源分发版,并且针对Windows进行了更好的优化。