2

我有一个 Perl 脚本,需要在后台启动另一个进程并退出,而无需等待其他脚本完成。StackOverflow 上有很多线程涉及如何在 Perl 中等待或如何不等待其他编程语言,但我似乎无法为 Perl 找到正确的答案。

我已经阅读了很多,并认为我在做正确的事情,但我的尝试似乎都没有正常工作。以下是我迄今为止尝试过的所有变体均无济于事:

system(qq|perl /util/script.pl $id|);

system(qq|perl /util/script.pl $id &|);

exec(qq|perl /util/script.pl $id|);

exec(qq|perl /util/script.pl $id &|);

对于这些中的每一个,父进程继续等待子进程在退出之前完成。请让我知道我做错了什么以及分叉后台进程的正确方法。

在此先感谢您的帮助!


帮助调试的完整代码。请注意,API->Function() 调用是我们的代码库用于数据库交互等特定功能的面向对象模块:

sub Add {
    my $self = shift;
    my $domain = shift;

    if(!$self->IsValid($domain)) { return; }

    my $SQL = qq| insert into domains set added=NOW(),domain=| . API->Database->Quote($domain);
    my $sth = API->DatabaseQuery($SQL);

    $SQL = qq| select last_insert_id() |;
    $sth = API->DatabaseQuery($SQL);
    my $id = $sth->fetchrow_array();

    my $command = qq|perl /home/siteuser/util/new.pl $id &|;
    system($command);

    return {'id'=>$id,'domain'=>$domain};
}
4

4 回答 4

4

第一个旨在以这种方式工作 -system执行命令并完成它以结束。

最后两个也是这样设计的——exec特别是设计为永不返回。它基本上用子进程替换了父进程。

但是,第二个应该可以解决问题:从system调用中启动的命令是 shell,它被赋予了要执行的字符串。由于字符串以“&”结尾,这意味着 shell 将作为后台进程启动您的命令,并在启动后完成自己的执行。

您能否发布更多代码来说明#2如何不起作用?

另外,看看如果你尝试反引号或 qx 会发生什么:

my $output = qx|perl /util/script.pl $id &|;
print $output;

另外,作为减少未知数的一种方式,您能否运行以下命令并告诉我打印的内容:

my $output = qx|(echo "AAAAAAA"; /bin/date; sleep 5; /bin/date; echo "BBBBBBB") &|;
print $output;
于 2010-12-13T17:41:11.053 回答
3

Are you calling fork() before calling system or exec?

my $pid = fork();
if (defined($pid) && $pid==0) {
    # background process
    my $exit_code = system( $command );
    exit $exit_code >> 8;
}


my $pid = fork();
if (defined($pid) && $pid==0) {
    # background process
    exec( $command );
    # doesn't^H^H^H^H^H^H shouldn't return
}
于 2010-12-13T18:09:36.353 回答
3

You need to disassociate the child from the parent. See perldoc -q daemon. Or Proc::Daemon

于 2010-12-13T18:56:12.723 回答
0

使用 fork 是后台进程的好方法:

my $pid = fork;
die "fork failed" unless defined $pid;
if ($pid == 0) {
    # child process goes here
    do '/util/script.pl';
    exit;
}
# parent process continues here
于 2010-12-13T18:00:16.127 回答