Linux 为什么';是否等待进程退出?
在下面的脚本中,我试图弄清楚Linux 为什么';是否等待进程退出?,linux,perl,waitpid,Linux,Perl,Waitpid,在下面的脚本中,我试图弄清楚waitpid是如何工作的,但它不会等待ssh进程退出done立即打印,而不是在ssh过程存在之后打印 问题 如何使waitpid仅在给定的pid退出时继续 #!/usr/bin/perl use strict; use warnings; use Parallel::ForkManager; use POSIX ":sys_wait_h"; my $pm = Parallel::ForkManager->new(5); my $pid = $pm->s
waitpid
是如何工作的,但它不会等待ssh
进程退出done
立即打印,而不是在ssh
过程存在之后打印
问题
如何使waitpid
仅在给定的pid退出时继续
#!/usr/bin/perl
use strict;
use warnings;
use Parallel::ForkManager;
use POSIX ":sys_wait_h";
my $pm = Parallel::ForkManager->new(5);
my $pid = $pm->start;
my $p = $pid;
if (!$pid) {
system("ssh 10.10.47.47 sleep 10");
$pm->finish;
}
$p = qx(/usr/bin/pgrep -P $p);
print "ssh pid is $p\n";
my $kid;
do {
$kid = waitpid($p, 0);
} while $kid > 0;
print "done\n";
我也试过了
while (1) {
$p = kill 0, $p;
print "x";
sleep 1 if $p;
print "*";
last unless $p;
}
但是由于某种原因,它甚至没有到达第一个
打印
,并且永远不会退出。等待函数族只在子进程上工作,甚至等待PID
。睡眠过程不是你的孩子,而是你孩子的孩子。这是因为system
本质上是fork
+exec
。通过使用Parallel::ForkManager+系统,您正在分叉,然后再次分叉,然后执行sleep
既然您已经使用了fork,那么应该使用exec。这有一个额外的优点,即不需要调用pgrep,并且它存在计时问题(即,在孩子执行系统之前,家长可能会调用pgrep)
为了简单起见,它现在使用睡眠。来自Perl的警告“语句不太可能到达”必须被抑制,因为Perl没有意识到$pm->start
已经分叉。这应该是没有警告的“exec”
,但这不起作用,所以我不得不抑制它们
my $pm = Parallel::ForkManager->new(5);
my $pid = $pm->start;
my $p = $pid;
if (!$pid) {
no warnings; # no warnings "exec" is not working
exec("sleep 10");
$pm->finish;
}
print "sleep pid is $p\n";
waitpid($p, 0);