gpt4 book ai didi

linux - 为什么waitpid不等待进程退出呢?

转载 作者:IT王子 更新时间:2023-10-29 00:20:26 25 4
gpt4 key购买 nike

在下面的脚本中,我试图弄清楚 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;
}

但由于某种原因它甚至没有到达第一个 print 并且永远不会退出。

最佳答案

wait 系列函数仅适用于子进程,甚至 waitpid。 sleep 过程不是你的 child ,而是你 child 的 child 。这是因为 system 本质上是 fork + exec。通过使用 Parallel::ForkManager + 系统,您正在 fork ,然后再次 fork ,然后执行 sleep 。

既然你已经 fork 了,你应该使用 exec。这具有不需要调用 pgrep 的额外优势,并且它是时间问题(即,父级可能会在子级执行系统之前调用 pgrep)。

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);

为简单起见,它现在使用 sleep 。必须禁止来自 Perl 的警告“不太可能达到语句”,因为 Perl 没有意识到 $pm->start 已经 fork 。这应该是 no warnings "exec" 但这不起作用,所以我不得不将它们全部抑制。

关于linux - 为什么waitpid不等待进程退出呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27677077/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com