我有一个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};
}
答案 0 :(得分: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;
答案 1 :(得分:3)
在致电fork()
或system
之前,您是否在致电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
}
答案 2 :(得分:3)
您需要取消孩子与父母的关联。 请参阅perldoc -q守护程序。或Proc::Daemon
答案 3 :(得分: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