【问题标题】:Perl 6 blocks on awaiting killed Proc::AsyncPerl 6 阻塞等待被杀死的 Proc::Async
【发布时间】:2019-06-26 09:52:28
【问题描述】:

我有一个 perl6 程序,它通过Proc::Async 运行一个外部程序并尝试读取它的stdout。应该读取标准输出的代码部分可能会以某种方式失败,但程序的其他部分实际上会杀死外部进程以清理内容。但是,在杀死这样的进程之后,然后等待承诺,它会永远阻塞......,我怎样才能避免 perl6 阻塞等待被杀死的 Proc::Asyncstdout 被管道但未被消耗?我认为以下 sn-p 说明了问题:

#!/usr/bin/env perl6
#

my $proc = Proc::Async.new(<cat /dev/urandom>);
my $supply = $proc.stdout(:bin);
my $promise = $proc.start;

$proc.ready.then: {
    shell <<ps auxf | grep [u]random>>;
    put "Terminating process {$_.result} …";
    $proc.kill(SIGTERM);
}
sleep 1;
if shell(<<ps auxf | grep [u]random>>).exitcode ≠ 0 {
    put "processed killed!";
}

put "awaiting $proc ({$proc.command}) …";
await $promise;  # <--- blocked here :(

【问题讨论】:

    标签: raku


    【解决方案1】:

    start 返回的Promise 仅在任何获得的输出流中的Supply 传递其所有事件后才会保留。这意味着可以假设在保留Promise 时所有输出都已交付,这总体上大大简化了Proc::Async 的工作(如果没有这种行为,我们可能会看到大量错误的程序丢失输出) .但是,如果从未点击过 Supply,那么就不可能发生这种情况,因此会挂起。

    解决方法是.tapstdoutSupply不提供任何回调:

    $proc.stdout(:bin).tap;
    

    这将简单地丢弃输出。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-14
      • 1970-01-01
      • 2022-01-04
      • 2014-06-27
      相关资源
      最近更新 更多