Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 如何使用IO::Async和数组作为输入?_Perl_Io Async - Fatal编程技术网

Perl 如何使用IO::Async和数组作为输入?

Perl 如何使用IO::Async和数组作为输入?,perl,io-async,Perl,Io Async,我有一个循环: foreach my $element ( @array ) { my $result = doSomething($element); } 由于数组是否按顺序处理并不重要,而且脚本运行时间较长,因此我希望异步运行doSomething() 我正在寻找这个,但是我似乎找不到一个例子,其中循环的输入是上面提到的一个简单数组。这个例子似乎集中在开放式插座、标准输入等方面 下面是给出的示例,显示了通过STDIN将数据馈送到循环: $loop->add( IO::Asy

我有一个循环:

foreach my $element ( @array ) {
     my $result = doSomething($element);
}
由于数组是否按顺序处理并不重要,而且脚本运行时间较长,因此我希望异步运行
doSomething()

我正在寻找这个,但是我似乎找不到一个例子,其中循环的输入是上面提到的一个简单数组。这个例子似乎集中在开放式插座、标准输入等方面

下面是给出的示例,显示了通过STDIN将数据馈送到循环:

$loop->add( IO::Async::Stream->new_for_stdin(
   on_read => sub {
      my ( $self, $buffref, $eof ) = @_;

      while( $$buffref =~ s/^(.*)\n// ) {
          print "You typed a line $1\n";
      }

      return 0;
   },
) );

如何为其提供数组元素呢?

正如@StefanBecker所评论的,最简单的处理方法是使用数组元素

从文档中:

的这个子类将函数体包装在工作进程集合中,以允许它独立于主进程执行

IO::Async
框架中,
IO::Async::Function
的典型用例是需要异步执行阻塞过程

免责声明:请注意,正如@zdim所评论的,
IO::Async
可能不是最适合您的用例的。在这里,像这样的纯流程并行化程序可能是您的最佳选择,因为它基本上实现了相同的功能(分叉和并行执行),但以更直接的方式实现。
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\u all(@futures)->wait
也可以写成
$\u->get for@futures
,但是第一个表达式使用收敛期货,它的优点是它永远不会失败,即使底层调用实际上已经死亡


NB2:IO::Async::Function和Future中提供了许多选项,用于处理错误、管理工作人员数量及其行为等。查看文档了解更多详细信息…

由于您提供了大量信息,很难给您一个好的答案。请在您的帖子中添加一些相关的示例代码,以充实
doSomething
。您很可能希望
doSomething
启动一个异步请求并让它返回一个句柄。然后收集这些句柄并等待它们指示它们已完成。听起来您应该使用
doSomething
作为代码块查看,例如
IO::Async::Function
。然后循环可以使用
$function->call()
传入参数并将调用结果存储在数组中。然后,您需要第二个循环来获取异步函数调用,也就是说,该代码将“阻止”等待结果。
IO::async::Routine
可能也适用。手册页中的示例看起来可以直接修改以解决您的问题。您只需定义循环的停止条件,可能是在所有函数返回时达到0的计数器?您在文档中看到的示例没有向您展示您想要什么,因为这首先是一个事件处理系统。是的,您可以将它用于任何异步处理,但这不是框架的主要用途。为什么不
Parallel::ForkManager
,什么似乎正好适合您的需要?这将是几行代码,概念上更简单。对于
IO::Async::Function
解决方案:
foreach(…){push(@futures,$Function->call($element));}Future->wait_all(@futures)而不是
$\->get for@futures
你可以在它们完成时使用组合来解析它们:
Future->wait\u all(@futures)->wait
await
只是
get
,它不会返回成功或在失败时抛出异常,并且
wait\u all
不会失败。)如果您希望将来能够优雅地处理失败(在本例中,函数中抛出异常),当然还有很多其他选项,等等。我个人更喜欢IO::Async::Function作为解决方案,因为事件循环和未来提供了与程序其余部分集成的灵活性。@Grinnz:谢谢您的评论,相应地更新了答案。是的,我也很喜欢IO::Async和Future,我发现它非常棒。我同意使用futures更好(但是也许一点评论会帮助不熟悉的人?)。那么为什么不呢?@zdim:当然,谢谢。。。更新我的答案(见NB1)