繁体   English   中英

承诺不并行运行

[英]Promises in not running in parallel

我正在尝试使用Promises模块来并行运行一个进程。 我的要求不是分叉一个新进程并让它运行。

我试过这段代码,但它没有并行执行

use AnyEvent::HTTP;
use JSON::XS qw[ decode_json ];
use Promises qw[ collect deferred ];
use Data::Dumper;

sub process {
    my ($data) = @_;
    my $d = deferred;

    for (1..5) {
        print "\n$data " . $_ * $data;
    }

    $d->resolve($data);

    $d->promise;
}


collect(
    process(10),
    process(20),
    process(30),
)->then(
    sub {
        print Dumper(\@_);
    },
);

1;

输出是

10 10
10 20
10 30
10 40
10 50
20 20
20 40
20 60
20 80
20 100
30 30
30 60
30 90
30 120
30 150$VAR1 = [
          [
            10
          ],
          [
            20
          ],
          [
            30
          ]
        ];

这有什么问题?

Promise 是一种构造回调的机制,而不是一种并行运行代码的方法。 回调和并行之间有一些联系,因为两者都可以用于异步编程,如果我们必须等待某些东西,我们会运行另一段代码。 没有线程,需要你使用一些事件循环,并在等待时告诉事件循环。

常见的 Perl 事件循环是来自 Mojolicious Web 框架的IO::AsyncMojo::IOLoop

Perl 并没有真正做多线程——线程实际上是一个fork()仿真(参见threads警告),而且绝对不是你从 Java 中知道的那种线程。

看起来您已经从Promises中获取了概要代码,并删除了事件循环模块AnyEvent::HTTP以及对它的所有调用。 这就是为什么您的程序无法按预期运行的原因

Promises本身不能提供并行性:它需要一个事件循环来创建可以“并行”运行的多个进程,但是 CPAN 上的任何事件循环模块都可以

您想将并行性用于什么目的? 事件循环模块的正确选择将使一切变得不同

但是不要忘记,除非您的程序的活动是受磁盘限制或受网络限制的,否则您不太可能看到性能的重大改进。 多处理是一种错觉,操作系统将在进程之间分配处理器时间,但只有一个处理器,经过的时间总是比单独运行的等效进程多

如果您想要一种允许并行执行的替代方法,使用基于 fork 的 Promise,还有Promise::Me 有了这个,您可以轻松地执行以下操作:

my $p = Promise::Me->new(sub
{
    # Some code to execute
})->then(sub
{
    my( $resolve, $reject ) = @$_;
    my $res = shift( @_ ); # return value from the code executed above
    # more processing...
    # You can use $resolve->( $some_data ); to resolve or $reject->( $some_exception ); to reject.
})->then(sub
{
    my $more = shift( @_ ); # return value from the previous then
    # more processing...
})->catch(sub
{
    my $exception = shift( @_ ); # error that occured is caught here
})->finally(sub
{
    # final processing
})->then(sub
{
    # A last then may be added after finally
};

每个promise都将异步执行,并且独立于其他promise。

作为全面披露,我是Promise::Me的作者。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM