2

我正在尝试在不同平台上并行运行几个子进程。只有在所有子进程在各自平台上完成后,父进程才能继续进行。

问题是当我使用 fork 然后在子进程中运行“exec”命令时,它几乎立即结束。此外,输出不一致。几乎每次日志都只显示一行。

-bash-2.05b$ cat Agent.SOLSPARC
caught SIGTERM signal, cleaning up

或者

-bash-2.05b$ cat Agent.SOLSPARC
Host: EBSO9SPC  Login: esm2 

有时,很少有多余的行,最后是消息,“被信号 15 杀死”。我在“exec”中使用的命令实际上调​​用了一个脚本,该脚本连接到远程盒子并在它们上运行 make 命令。出于测试目的,我目前只通过一个平台,即 SOLSPARC。另外,我只对知道命令是否在任何给定平台上完成感兴趣。

我不确定我是否正确地将所有参数传递给'exec',所以我尝试了不同的组合(在引用了互联网上的不同链接之后)但无济于事。一个重要的观察结果是,当我使用 strace 调试此问题时,该命令运行良好。我在 perldoc 中看到 exec 在 Unix 平台上使用/bin/sh -c,但在其他平台上有所不同。是 exec 和 strace 使用不同的外壳吗?

这是我的代码的相关部分:

sub compile {
    my %child_pids;
    foreach $plat (0 .. $#plat_list) {
        my $pid = fork;
        # Didn't check the undef condition for child
        if ($plat_list[$plat] eq "SOLSPARC") {
            print "\nStarted Solaris build \n";
            if ($pid == 0) {
                print "Inside Child Process \n\n";
                exec ( "${ROOT}/${REM_EXEC} -t 1200 -c \"make LANG=en_US distclean \" -b ${ROOT} -l Agent. $plat_list[$plat]" ) or die "exec failed";
            } elsif ($pid > 0) {
                $child_pids{"SOLSPARC"} = $pid;
            }
        } else {
           print "\nStarted build for other platforms \n";
           if ($pid == 0) {
                print "Inside Child Process \n\n";
                exec ( "${ROOT}/${REM_EXEC} -t 1200 -c \"make LANG=en_GB clean \" -b ${ROOT} -l Agent. $plat_list[$plat]" ) or die "exec failed";     
           } elsif ($pid > 0) {
                $child_pids{"$plat_list[$plat]"} = $pid;
           }
        }
    }


    my %rev_child_pids = reverse %child_pids;
    while ((my $kid = waitpid -1, WNOHANG) > 0) {
        if ($rev_child_pids{$kid} eq "SOLSPARC") {
            print "\nChild process completed for SOLARIS platform $rev_child_pids{$kid} \n";
            print "Run some other command here \n";
        } else {
            print "\nChild process completed for other platform $rev_child_pids{$kid} \n";
            print "No more commands to run \n";
        }
    }
}

有什么建议么?

4

1 回答 1

0

尝试使用“系统”而不是“执行”。

system `${ROOT}/${REM_EXEC} -t 1200 -c "make LANG=en_US distclean " -b ${ROOT} -l Agent. $plat_list[$plat]` 

'system' 与 fork 的工作方式略有不同,因此它可能会解决问题。

于 2013-04-18T17:43:50.710 回答