简体   繁体   English

承诺不并行运行

[英]Promises in not running in parallel

I am trying to use the Promises module to run a process in parallel.我正在尝试使用Promises模块来并行运行一个进程。 My requirement is not forking a new process and let it run.我的要求不是分叉一个新进程并让它运行。

I tried this code but it is not executing in parallel我试过这段代码,但它没有并行执行

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;

The output is输出是

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
          ]
        ];

What is wrong with this?这有什么问题?

Promises are a mechanism to structure callbacks , not a way to run code in parallel . Promise 是一种构造回调的机制,而不是一种并行运行代码的方法。 There is some connection between callbacks and parallelism because both can be used for asynchronous programming , where we run another piece of code if we have to wait for something.回调和并行之间有一些联系,因为两者都可以用于异步编程,如果我们必须等待某些东西,我们会运行另一段代码。 Without threads, requires that you use some event loop , and also tell the event loop when you are waiting.没有线程,需要你使用一些事件循环,并在等待时告诉事件循环。

Common Perl event loops are IO::Async , and Mojo::IOLoop from the Mojolicious web framework.常见的 Perl 事件循环是来自 Mojolicious Web 框架的IO::AsyncMojo::IOLoop

Perl doesn't really do multithreading – the threads are effectively a fork() emulation (see the threads warning ), and definitively not the kind of threads you know from Java. Perl 并没有真正做多线程——线程实际上是一个fork()仿真(参见threads警告),而且绝对不是你从 Java 中知道的那种线程。

It looks like you've taken the synopsis code from Promises and removed the event loop module AnyEvent::HTTP and all calls to it.看起来您已经从Promises中获取了概要代码,并删除了事件循环模块AnyEvent::HTTP以及对它的所有调用。 That is why your program doesn't work as you expect这就是为什么您的程序无法按预期运行的原因

Promises can't supply parallelism on its own: it needs an event loop to create multiple processes that can run "in parallel", but any event loop module on CPAN will do fine Promises本身不能提供并行性:它需要一个事件循环来创建可以“并行”运行的多个进程,但是 CPAN 上的任何事件循环模块都可以

What is it that you want to use parallelism for?您想将并行性用于什么目的? The right choice of event loop module will make all the difference事件循环模块的正确选择将使一切变得不同

But don't forget that, unless your program's activity is disk-bound or network-bound, you are unlikely to see a major improvement in performance.但是不要忘记,除非您的程序的活动是受磁盘限制或受网络限制的,否则您不太可能看到性能的重大改进。 Multi-processing is an illusion whereby the operating system will distribute processor time amongst processes, but with only a single processor the elapsed time will always be rather more than the equivalent process run in isolation多处理是一种错觉,操作系统将在进程之间分配处理器时间,但只有一个处理器,经过的时间总是比单独运行的等效进程多

If you want an alternative approach that allows for parallel execution, using fork-based promise, there is also Promise::Me .如果您想要一种允许并行执行的替代方法,使用基于 fork 的 Promise,还有Promise::Me With this, you could easily do something like:有了这个,您可以轻松地执行以下操作:

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
};

Each promise would be executed asynchronously and independently of the others.每个promise都将异步执行,并且独立于其他promise。

As a full disclosure, I am the author of Promise::Me .作为全面披露,我是Promise::Me的作者。

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

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