Perl中的非阻塞/异步执行

时间:2011-12-17 22:02:26

标签: perl asynchronous parallel-processing nonblocking

有没有办法在Perl中实现非阻塞/异步执行(没有fork()')?

我曾经是一名Python开发人员多年...... Python拥有非常棒的'Twisted'框架允许这样做(使用DEFERREDs。当我运行搜索以查看Perl中是否有任何内容同样地,我遇到了POE framework - 这似乎与我正在寻找的东西“接近”。但是......花了一些时间阅读文档并“玩”代码后,我反对“ wall“ - 遵循限制(来自POE::Session文档):

  

回调不是先发制人的。只要一个人正在运行,就不会派遣其他人。这称为协作式多任务处理。每个会话必须通过返回中央调度内核进行合作。

这种限制本质上违背了异步/并行/非阻塞执行的目的 - 通过限制在任何给定时刻执行的只有一个回调(代码块)。没有其他回调可以开始运行,而另一个回调已经在运行!

所以......在Perl中有没有办法在没有fork()的情况下实现多任务(并行,非阻塞,异步执行代码) - 类似于Python中的DEFERREDs? / p>

6 个答案:

答案 0 :(得分:11)

Coro是POE和线程之间的混合。从阅读它的CPAN文档,我认为IO :: Async可以实现真正的异步执行。 threads也可以使用 - 至少Padre IDE成功使用它们。

答案 1 :(得分:8)

我对Twisted或POE不太熟悉,但基本的并行执行非常简单threads。解释器通常不会使用线程支持进行编译,因此您需要检查它。 forks包是线程的替代品(实现完整的API),但无缝使用进程。然后你可以做这样的事情:

my $thread = async {
    print "you can pass a block of code as an arg unlike Python :p";
    return some_func();
};
my $result = $thread->join();

我确实在使用forks的异步进程中实现了来自事件循环的回调,但我不明白为什么它不适用于线程。

答案 2 :(得分:3)

Twisted也使用合作多任务,就像POE& Coro

然而,Twisted Deferred看起来像(或可以)使用线程。 NB。请参阅SO问题answer

中的Twisted: Making code non-blocking

所以你需要使用POE走同一条路线(虽然使用fork is probably preferable)。

因此可以使用一个POE解决方案:POE::Wheel::Run - 在子流程中可移植地运行阻止代码和程序

对于POE的替代方案,请查看AnyEventReflex

答案 3 :(得分:0)

我相信你使用select来做这件事。与分叉更相似的是,threading

答案 4 :(得分:0)

如果你想要异步处理但是只使用一个cpu(核心)就可以了。 例如,如果应用程序受I / O限制,则大多数时间单个进程就足够了。

答案 5 :(得分:0)

  

当另一个回调已经在运行时,没有其他回调可以开始运行!

据我所知 - 所有语言都是一样的(当然每个CPU线程;现代Web服务器通常每个CPU核心产生至少一个进程或线程,所以它看起来(对用户)就像它的东西一样并行工作,但长时间运行的回调没有被打断,其他一些核心就是这样做了。)

除非中断的中断已经过专门编程以适应中断,否则不能中断中断。

想象一下需要1分钟才能运行的代码,以及一个拥有16个内核的PC - 现在想象有一百万人试图加载该页面,你可以将工作结果交付给16个人,并且剩下的就是“超时”,或者你可能会使您的Web服务器崩溃,并且不会向任何人提供任人们选择不让他们的Web服务器崩溃,这就是为什么他们永远不允许回调中断其他回调的原因(即使他们尝试过也不会这样 - 调用者永远无法控制回来在前一个调用结束之前进行新的调用.. 。)