当后台进程在Perl中终止时,如何通知我?
我编写了一个Perl程序,它在子进程中分叉并调用后台程序,并且有一个无休止的while循环,它在父进程中执行一些操作。现在,当子进程中的后台程序终止时,应保留while循环:当后台进程在Perl中终止时,如何通知我?,perl,fork,Perl,Fork,我编写了一个Perl程序,它在子进程中分叉并调用后台程序,并且有一个无休止的while循环,它在父进程中执行一些操作。现在,当子进程中的后台程序终止时,应保留while循环: $pid = fork(); if ( !$pid ) { exec( "program args" ); } else { while ( 1 ) { # do something # needs help: if program terminated, break
$pid = fork();
if ( !$pid ) {
exec( "program args" );
} else {
while ( 1 ) {
# do something
# needs help: if program terminated, break
}
}
我猜,exec()正在阻塞,因此在程序退出之前它不会返回,但我可能错了。好吧,
fork
将子进程的PID(您在代码中尽职尽责地检索)提供给父进程。这正是父母可以照顾孩子的原因
要在循环终止时离开循环,可以使用
kill 0$pid
检查子循环是否仍然存在。请参见perldoc-f kill
您需要一个信号处理程序来处理当子进程退出时父进程被发送的CHLD信号。(有关perl中信号处理的更多详细信息,请参见perldoc-perlipc
)
您可以在else循环中执行以下操作来获取子进程。
或者,您可以将
$SIG{CHLD}='IGNORE'
设置为不担心子进程变成僵尸。根据您的应用程序,您可以不时检查子进程是否结束,父进程是否可以完成。您可以将posix waitpid()与WNOHANG一起使用,以执行无阻塞等待,或者发出信号检查您的孩子是否仍在运行,或者可以使用管道(在关闭时检查)。我个人会使用waitpid()。perlipc中有一个很好的例子解释 -1不,该程序之前使用了fork
,因此只有一个子进程将使用exec
,这是正确的。问题是该进程正在变成僵尸,因此该命令仍然返回true。不过,当设置$SIG{CHLD}='IGNORE'(请参阅下一个答案)时,该命令仍然有效。感谢您的提示。我把它和上面的提示结合起来了
...
} else {
$SIG{CHLD} = \&reaper
}
# hash to store exit status of child processes
our %child;
sub reaper {
my $x;
while (($x = waitpid(-1,WNOHANG)) >0) {
$child{$x} = $? >> 8;
}
}