为什么perl执行命令比单独运行命令需要更长的时间?

时间:2018-04-16 14:27:17

标签: apache perl

当我运行命令

montage -background black -geometry +0+0 -mode Unframe -tile ${num_digits}x1 $filelist gif:- > ~/temp/count.gif

执行需要0.1秒(我使用time montage...)。

当我将该命令放入我的perl cgi脚本

print LOG "starting montage\n";
open(GRFX,
    "montage -background black -geometry +0+0 -mode Unframe -tile ${num_digits}x1 $filelist gif:- |"
);
print LOG "finish montage\n";
print <GRFX>;
print LOG "finish output\n";
close(GRFX);

完成蒙太奇之间的时间&#34;并且&#34;完成输出&#34;是6秒!!

如果我从命令行运行cgi脚本需要0.1秒。但是从Apache内部需要6秒,即使在与Apache在同一台计算机上使用浏览器进行访问时(因此,不是因特网减慢了速度,所有其他页面加载速度都很快,无论浏览器是否在同一台计算机上)。

蒙太奇生成的gif文件是1.7k。

为什么在Apache中运行时这么慢?

唯一的标头输出是print "Content-type: image/gif\n\n";

1 个答案:

答案 0 :(得分:1)

您正在使用print <GRFX>;打印输出,读取管道shell命令的所有输出行。

LINES 是这里的有效词。据推测,尾随的字节序列并不以换行符结束,因此Perl正在等待它。最终,它会超时。

您可以将local $/ = 4096设置为一次读取4096个字节的块。然后,使用print while <GRFX>输出。

同样binmode GRFXSTDOUT也是一个不错的表格,所以你不能problems like this。另请参阅blog post上的related question

我很想重写这样的代码(未经测试):

sub output_image {
    my $num_digits = shift;
    my $filelist = shift;

    print LOG "starting montage\n";

    my @cmd = (
        montage => qw(
        -background black
        -geometry +0+0
        -mode Unframe
        -tile),
        "${num_digits}x1",
        split(/ /,$filelist),
        'gif:-'
    );

    open my $GRFX, '-|', @cmd
        or die "Failed to open pipe: $!";

    {
        local $/ = 4096;
        binmode $GRFX;
        binmode STDOUT;
        print while <$GRFX>;
    }

    close $GRFX
        or die "Failed to close pipe: $!";

    print LOG "finish montage\n";
}