如何判断 IPC::Run 作业何时完成
How to tell when an IPC::Run job has finished
是否有一种简单、可靠的方法来判断 IPC::Run
任务何时完成,即是否有任何 child 个进程已退出?
文档对此惊人地沉默。
似乎在 pumpable
上循环是可行的,尽管它并没有真正被清楚地记录为正确的做事方式:
use strict;
use warnings;
use IPC::Run;
use 5.12.0;
my $handle = IPC::Run::start(['sleep', '10']);
while ($handle->pumpable)
{
sleep(0.5);
# do other stuff in the event loop
# so we don't want to block on finish
}
$handle->finish;
print("exited with '" . $handle->result . "'");
还有更好的选择吗? finish
块,但是在等待过程完成时你不能在事件循环中做其他工作。
我很惊讶没有一个简单的
$handle->running
或
$handle->finished
我是不是遗漏了什么明显的东西?
同样,似乎没有记录的方法来获取 child(ren) 的 pid。
这是获取 child PID 的解决方法。然后您可以等待 child 或设置 SIGCHLD 处理程序。例如:
use feature qw(say);
use strict;
use warnings;
use IPC::Run qw( start );
use Proc::ProcessTable;
my $h = start ['sleep', '5'];
my $pt = Proc::ProcessTable->new();
my $kid;
for my $p (@{ $pt->table } ){
if ( $p->ppid == $$ ) {
if ( $p->cmndline =~ m{/bin/sleep} ) {
$kid = $p->pid;
}
}
}
if ( defined $kid ) {
say "Waiting for child with PID '$kid' to finish..";
waitpid $kid, 0;
say "Done.";
}
else {
die "Could not find PID of child process\n";
}
我还没有找到一种干净的方法来做这两种事情,只能找到其他方法。
关于children是否是运行的信息可以通过result
相关方法得到,也可以通过pumpable
(题中已经用到的)得到。
result
方法“如果传递 out-of-range child 数字 则抛出异常”。如果我们在没有孩子退出时查询,就会发生这种情况。因此,使用单个 child 进程
sub only_kid_finished { eval { $_[0]->result }; return $@ ? 0 : 1 }
更好的是,results
方法 return 是 child 退出值的列表,同时它还“如果线束未处于完成状态则抛出异常”。所以它可以以相同的方式使用,但对于更多的孩子,它也可以用来跟踪还剩多少 exited/are。
如问题中所用,pumpable
还可以告知是否有任何进程 运行
sub any_kids_left { return $_[0]->pumpable }
它与 I/O 渠道或流程有关,但如果有任何内容 运行 则必须 return 为真,否则为假。
children PID这个问题让我有点头疼,因为这是一个可能需要知道的信息。虽然它在 object、$handle->{KIDS}[0]{PID}
(对于第一个孩子)中是正确的,但我不知道如何以合理的方式检索它。我认为这个基本结构无法改变,所以它会诱使我实际使用它,并进行检查。那么我也会对我可能得到的任何东西感到满足,因为我应得的。
一旦检索到 PID,就可以使用 kill 0, $pid
检查进程。请注意,此 return 为真 (1
) 直到进程被回收(即使它退出但为僵尸)。
是否有一种简单、可靠的方法来判断 IPC::Run
任务何时完成,即是否有任何 child 个进程已退出?
文档对此惊人地沉默。
似乎在 pumpable
上循环是可行的,尽管它并没有真正被清楚地记录为正确的做事方式:
use strict;
use warnings;
use IPC::Run;
use 5.12.0;
my $handle = IPC::Run::start(['sleep', '10']);
while ($handle->pumpable)
{
sleep(0.5);
# do other stuff in the event loop
# so we don't want to block on finish
}
$handle->finish;
print("exited with '" . $handle->result . "'");
还有更好的选择吗? finish
块,但是在等待过程完成时你不能在事件循环中做其他工作。
我很惊讶没有一个简单的
$handle->running
或
$handle->finished
我是不是遗漏了什么明显的东西?
同样,似乎没有记录的方法来获取 child(ren) 的 pid。
这是获取 child PID 的解决方法。然后您可以等待 child 或设置 SIGCHLD 处理程序。例如:
use feature qw(say);
use strict;
use warnings;
use IPC::Run qw( start );
use Proc::ProcessTable;
my $h = start ['sleep', '5'];
my $pt = Proc::ProcessTable->new();
my $kid;
for my $p (@{ $pt->table } ){
if ( $p->ppid == $$ ) {
if ( $p->cmndline =~ m{/bin/sleep} ) {
$kid = $p->pid;
}
}
}
if ( defined $kid ) {
say "Waiting for child with PID '$kid' to finish..";
waitpid $kid, 0;
say "Done.";
}
else {
die "Could not find PID of child process\n";
}
我还没有找到一种干净的方法来做这两种事情,只能找到其他方法。
关于children是否是运行的信息可以通过result
相关方法得到,也可以通过pumpable
(题中已经用到的)得到。
result
方法“如果传递 out-of-range child 数字 则抛出异常”。如果我们在没有孩子退出时查询,就会发生这种情况。因此,使用单个 child 进程
sub only_kid_finished { eval { $_[0]->result }; return $@ ? 0 : 1 }
更好的是,results
方法 return 是 child 退出值的列表,同时它还“如果线束未处于完成状态则抛出异常”。所以它可以以相同的方式使用,但对于更多的孩子,它也可以用来跟踪还剩多少 exited/are。
如问题中所用,pumpable
还可以告知是否有任何进程 运行
sub any_kids_left { return $_[0]->pumpable }
它与 I/O 渠道或流程有关,但如果有任何内容 运行 则必须 return 为真,否则为假。
children PID这个问题让我有点头疼,因为这是一个可能需要知道的信息。虽然它在 object、$handle->{KIDS}[0]{PID}
(对于第一个孩子)中是正确的,但我不知道如何以合理的方式检索它。我认为这个基本结构无法改变,所以它会诱使我实际使用它,并进行检查。那么我也会对我可能得到的任何东西感到满足,因为我应得的。
一旦检索到 PID,就可以使用 kill 0, $pid
检查进程。请注意,此 return 为真 (1
) 直到进程被回收(即使它退出但为僵尸)。