4

我正在尝试在 perl 中运行后台进程。我创建了一个子进程,用于调用另一个 perl 脚本。我想与这个子进程并行运行几行代码。子进程完成后。我想打印一行代码。

主脚本

#!/usr/bin/perl

$|=1;

print "before the child process\n";

my $pid = fork();

if (defined $pid)
{
    system("perl testing.pl");
}

print "before wait command\n";

wait();

print "after 20 secs of waiting\n";

测试.pl

#!/usr/bin/perl

print "inside testing\n";

sleep(20);

预期产出

在子进程之前
在等待命令之前
(应等待 20 秒再打印)
等待 20 秒后
4

3 回答 3

8

你的脚本有很多问题。总是:

use strict;
use warnings;

local使用特殊变量是一个好习惯。只有包含特殊值的变量undef才会为defined. 因此,所有其他值(甚至是0; 就是这种情况)对于defined. 在另一个脚本中,shebang是错误的。

#!/usr/bin/perl

use strict;
use warnings;

local $| = 1;

print "Before the child process\n";

unless (fork) {
    system("perl testing.pl");
    exit;
}

print "Before wait command\n";
wait;
print "After 20 secs of waiting\n";
于 2012-11-23T14:05:43.583 回答
7

perlipc 文档“后台进程”部分内容为

您可以在后台运行命令:

system("cmd &");

命令的STDOUTand STDERR(可能STDIN,取决于您的 shell)将与父级的相同。SIGCHLD由于双重fork发生,您无需捕捉;详情见下文。

在你的程序中为参数添加一个和号system可以极大地简化你的主程序。

#! /usr/bin/env perl

print "before the child process\n";

system("perl testing.pl &") == 0
  or die "$0: perl exited " . ($? >> 8);

print "before wait command\n";

wait;
die "$0: wait: $!" if $? == -1;

print "after 20 secs of waiting\n";
于 2012-11-23T13:53:47.143 回答
1

fork返回值处理确实有点棘手。 亚里士多德最近的文章有一个简洁明了的分叉习语,在你的例子中,它看起来像:

#!/usr/bin/env perl
use 5.010000;
use strict;
use warnings qw(all);

say 'before the child process';
given (fork) {
    when (undef) { die "couldn't fork: $!" }
    when (0) {
        exec $^X => 'testing.pl';
    } default {
        my $pid = $_;
        say 'before wait command';
        waitpid $pid, 0;
        say 'after 20 secs of waiting';
    }
}

注意exec $^X => '...'行:$^X变量保存了当前 Perl 可执行文件的完整路径,因此“正确的 Perl 版本”将得到保证。此外,system预分叉时调用毫无意义。

于 2012-11-26T03:45:10.013 回答