正如@StefanBecker 所评论的,使用 IO::Async 处理此问题的最简单方法是使用IO::Async::Function。
从文档:
IO::Async::Notifier的这个子类将函数体包装在一组工作进程中,以允许它独立于主进程执行。
在IO::Async
框架中,典型的用例IO::Async::Function
是阻塞进程需要异步执行。
免责声明:请注意,正如@zdim 所评论的那样,IO::Async
可能不是最适合您的用例。像Parallel::ForkManager这样的纯进程并行化器可能是您最好的选择,因为它基本上实现了相同的功能(并行分叉和执行),但以更直接的方式。的主要区别因素之一IO::Async
是它的 I/O 多路复用功能,您似乎没有在这里使用。
但是,既然您要求IO::Async
,这里是这种实现的一个例子:我变成doSomething
了一个虚拟方法,它只等待作为参数给出的时间量。这使您可以观察异步执行的效果。
use strict;
use warnings;
use IO::Async::Function;
use IO::Async::Loop;
use Future;
# dummy sub
sub doSomething {
my ( $delay ) = @_;
print "start waiting $delay second(s)\n";
sleep $delay;
print "done sleeping $delay second(s)\n";
return $delay;
}
# prepare the function for execution
my $loop = IO::Async::Loop->new;
my $function = IO::Async::Function->new( code => sub { return doSomething($_[0]) } );
$loop->add($function);
# trigger asynchronous processing
my @array = qw/5 2 4 0/;
my @futures = map { $function->call( args => [ $_ ] ) } @array;
# safely wait for all ops to complete
Future->wait_all(@futures)->await;
print "all done !\n";
这产生:
start waiting 5 second(s)
start waiting 2 second(s)
start waiting 4 second(s)
start waiting 0 second(s)
done sleeping 0 second(s)
done sleeping 2 second(s)
done sleeping 4 second(s)
done sleeping 5 second(s)
all done !
NB1:Future->wait_all(@futures)->await
也可以写成$_->get for @futures
,但是第一个使用收敛期货的表达式的优点是它永远不会失败,即使底层调用实际上死了。
NB2:许多选项可用于处理错误、管理工人数量IO::Async::Function
及其Future
行为等。查看文档以获取更多详细信息...