为什么在fork之后使用LibXML时Perl会崩溃?

时间:2011-11-03 20:19:56

标签: perl

我在解决这个问题时遇到了困难,但是在我在Perl中完成fork后,我已经将其缩小为使用XML :: LibXML。我在Windows XP上运行Strawberry Perl 5.12.0,以及XML :: LibXML 1.70。

我有一个脚本,我需要同时运行多个进程,获取XML输出并处理结果。如果我在Solaris机器上运行它,它运行得很好,我没有问题。但是,如果我在Windows上运行此命令,则会出现一个崩溃窗口,指出'perl.exe遇到了问题并需要关闭。'

以下是将生成错误的示例程序:

use strict;
use warnings;
use XML::LibXML;
use Try::Tiny;

my $cmds = ['cmd1', 'cmd2'];
my @pids = ();
foreach my $cmd (@{$cmds}) {

    my $pid = fork();

    if ($pid) {

        # parent
        push (@pids, $pid);
    } elsif ($pid == 0) {

        XML::LibXML->load_xml(string=>'<root />'); # <-- this will crash it
        exit 0;
    }
}

foreach my $ch_pid (@pids) {

    try {

        waitpid($ch_pid, 0);
    } catch {

        carp("Error on waitpid: $!");
    };
}
exit 0;

如果我只有一个进程,或者如果我没有fork,那么它将成功运行。如果我删除了load_xml调用(并且在子节点中没有任何内容),那么它将成功运行。

有谁知道造成这种情况的原因以及如何解决?

1 个答案:

答案 0 :(得分:4)

using XML::LibXML with threads时需要特别注意。其中一些(特别是关于最初加载模块)也将与叉子有关。

您可以尝试删除编译时加载(use XML::LibXML;行),然后在分叉后加载模块:

} elsif ($pid == 0) {
    require XML::LibXML;
    XML::LibXML->load_xml(string=>'<root />');
    exit 0;
}