【问题标题】:understanding Mojo::IOLoop recurring and subprocess理解 Mojo::IOLoop 循环和子流程
【发布时间】:2018-06-21 01:58:27
【问题描述】:

我在 './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~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上使用activeperl,(v5.20.2),期待您的帮助。

【问题讨论】:

  • 欢迎使用 Stack Overflow 和 Perl 标签。你好像忘记问问题了。
  • 对不起,我只是不明白 Mojo::IOloop 给出的东西。

标签: perl mojolicious


【解决方案1】:

首先,Mojo::IOLoop::Subprocess 在您的第三个示例中使用不正确。 documentation 声明 run 方法需要提供 2 个子例程,第一个是将在“后台”执行的子例程,并且应该返回结果值,如果有的话,将由第二个子例程处理。在您的情况下,您应该为@files 中的每个元素创建新的子流程对象。

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

【讨论】:

  • 感谢蒂姆!我根据您的回答编辑了我的 code3.pl!但错误“子进程不支持在 ... 的 fork 仿真”仍然存在(使用草莓 perl 5.26,WinXP)。我在谷歌找到了一些关于“d_pseudofork”的信息,下面的代码给出了详细信息:use Config qw(myconfig config_sh config_vars config_re); #print myconfig();打印 config_sh();输出为: d_printf_format_null='undef' d_procselfexe='undef' d_pseudofork='define' d_pthread_atfork='undef' d_pthread_attr_setscope='undef' d_pthread_yield='undef' d_ptrdiff_t='define' 好像“d_pseudofork”选项没问题?
  • 还有另一个问题:我希望在我的代码中发出 $loop 的 'finish' 事件来计算任务使用的时间,这似乎不起作用:(,知道吗?
猜你喜欢
  • 2017-10-07
  • 2016-08-08
  • 1970-01-01
  • 2016-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-06
  • 1970-01-01
相关资源
最近更新 更多