Raku Perl6:无法调用此对象(REPR:P6opaque;Parallel::ForkManager)
我试图在Perl6中使用Perl5的Raku Perl6:无法调用此对象(REPR:P6opaque;Parallel::ForkManager),raku,Raku,我试图在Perl6中使用Perl5的parallel::ForkManager 这几乎是对Perl5代码的精确翻译 CONTROL { when CX::Warn { note $_; exit 1; } } use fatal; role KeyRequired { method AT-KEY (\key) { die "Key {key} not found" unless self.EXISTS-KEY(key);
parallel::ForkManager
这几乎是对Perl5代码的精确翻译
CONTROL {
when CX::Warn {
note $_;
exit 1;
}
}
use fatal;
role KeyRequired {
method AT-KEY (\key) {
die "Key {key} not found" unless self.EXISTS-KEY(key);
nextsame;
}
}
use Parallel::ForkManager:from<Perl5>;
sub run_parallel (@cmd) {
my $manager = Parallel::ForkManager(8).new();
for (@cmd) -> $command {
$manager.start and $manager.next;
my $proc = shell $command, :out, :err;
if $proc.exitcode != 0 {
put "$command failed";
put $proc.out.slurp;
put $proc.err.slurp;
die;
}
$manager.finish;
}
$manager.wait_all_children;#necessary after all lists
}
my @cmd;
my Str $dir = 'A/1';
for dir($dir, test => /\.vcf\.gz$/) -> $vcf {
@cmd.append: "aws s3 cp $vcf s3://s3dir/$dir/"
}
put @cmd.elems;
run_parallel(@cmd);
控件{
当CX::Warn{
附注$;
出口1;
}
}
使用致命的;
需要角色密钥{
方法AT-KEY(\KEY){
除非self.EXISTS-Key(Key)存在,否则die“Key{Key}未找到”;
下一集;
}
}
使用Parallel::ForkManager:from;
并行子运行(@cmd){
my$manager=Parallel::ForkManager(8).new();
对于(@cmd)->$命令{
$manager.start和$manager.next;
my$proc=shell$command,:out,:err;
如果$proc.exitcode!=0{
放置“$命令失败”;
放入$proc.out.slurp;
放入$proc.err.slurp;
死亡
}
$manager.finish;
}
$manager.wait_all_children;#所有列表之后都需要
}
my@cmd;
我的Str$dir='A/1';
对于dir($dir,test=>/\.vcf\.gz$/)->$vcf{
@cmd.append:“aws s3 cp$vcf s3://s3dir/$dir/”
}
put@cmd.elems;
并行运行(@cmd);
基本上,我正在尝试并行化繁琐的shell命令
然而,这个神秘的错误出现了:
无法在中调用此对象(REPR:P6opaque;Parallel::ForkManager)
在块中2.aws_cp.p6线18处平行的子管道
2.aws_cp.p6第39行
为什么Perl6会这样说?怎么了?如何运行这些命令
也许有一种更为自然/惯用的方法可以在Perl6中并行运行shell命令?您可能希望了解如何使用which在线程中异步运行外部命令,而无需分叉单独的代码实例来执行此操作 Perl5的Parallel::ForkManager可能无法在Perl6中工作,因为Inline::Perl5是如何实现的 Perl5将Perl5编译器/运行时嵌入到Perl6中 Parallel::ForkManager希望Perl5是自己运行的 如果您确实让它做了一些事情,而不是生成错误,那么它可能会破坏Perl6运行时。主要问题是使用
fork
。有关为什么fork
是一个问题的更多信息,请参阅Bart Wiegmans(brrt)撰写的文章:
Perl6已经有一个类似的功能,更易于使用
sub-run_并行(@cmd){
my@children=do for(@cmd)->$command{
开始{
my$proc=shell$command,:out,:err;
如果$proc.exitcode!=0{
放置“$命令失败”;
放入$proc.out.slurp;
放入$proc.err.slurp;
死亡
}
}
}
等待孩子们;
}
start
是一个前缀,告诉运行时在不久的将来开始运行以下代码。它返回一个承诺。wait
获取承诺列表并返回其结果列表
start
基本上调用Promise.start
,类似于:
子开始(&code){
我的$promise=promise.new;
我的$vow=$promise.vow;
$*SCHEDULER.cue(
{$vow.keep(代码(| c))},
:捕获(->$ex{$vow.break($ex);}));
美元承诺
}
因此,它将使用$*调度程序中的全局可用线程池。如果你想使用一个单独的,你可以
sub-run_并行(@cmd){
my$*SCHEDULER=ThreadPoolScheduler.new(最大线程数=>8);
my@children=do for(@cmd)->$command{
开始{
my$proc=shell$command,:out,:err;
如果$proc.exitcode!=0{
放置“$命令失败”;
放入$proc.out.slurp;
放入$proc.err.slurp;
死亡
}
}
}
等待孩子们;
}
不过,使用Proc::Async会更有意义。我真的不建议尝试在Perl6中使用Perl5 forking代码,因为它有一个完全不同的管理器异步和并行代码系统。“forking”是这一尝试的正确术语,即并行运行shell命令@我明白了。我的观点是Perl6不使用Forking进行并行工作,而是使用线程。其他人指出了为什么他们认为P5的parallel::ForkManager
似乎不太可能与P6一起工作。我对此一无所知。以下内容完全独立于此,而是以涉及线程的方式将P6与P5一起使用。根据,“如果您想安全地使用多个内联::Perl5
interpeter,例如从Perl 6线程中,还可以添加-Dusemultiplicity
选项”。甚至可以尝试一下该模块,它适用于有许多进程要并行运行的情况。