有没有办法在Perl中实现非阻塞/异步执行(没有fork()
')?
我曾经是一名Python开发人员多年...... Python拥有非常棒的'Twisted'框架允许这样做(使用DEFERREDs。当我运行搜索以查看Perl中是否有任何内容同样地,我遇到了POE framework - 这似乎与我正在寻找的东西“接近”。但是......花了一些时间阅读文档并“玩”代码后,我反对“ wall“ - 遵循限制(来自POE::Session文档):
回调不是先发制人的。只要一个人正在运行,就不会派遣其他人。这称为协作式多任务处理。每个会话必须通过返回中央调度内核进行合作。
这种限制本质上违背了异步/并行/非阻塞执行的目的 - 通过限制在任何给定时刻执行的只有一个回调(代码块)。没有其他回调可以开始运行,而另一个回调已经在运行!
所以......在Perl中有没有办法在没有fork()
的情况下实现多任务(并行,非阻塞,异步执行代码) - 类似于Python中的DEFERREDs? / p>
答案 0 :(得分:11)
答案 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
所以你需要使用POE
走同一条路线(虽然使用fork is probably preferable)。
因此可以使用一个POE
解决方案:POE::Wheel::Run
- 在子流程中可移植地运行阻止代码和程序。
答案 3 :(得分:0)
答案 4 :(得分:0)
如果你想要异步处理但是只使用一个cpu(核心)就可以了。 例如,如果应用程序受I / O限制,则大多数时间单个进程就足够了。
答案 5 :(得分:0)
当另一个回调已经在运行时,没有其他回调可以开始运行!
据我所知 - 所有语言都是一样的(当然每个CPU线程;现代Web服务器通常每个CPU核心产生至少一个进程或线程,所以它看起来(对用户)就像它的东西一样并行工作,但长时间运行的回调没有被打断,其他一些核心就是这样做了。)
除非中断的中断已经过专门编程以适应中断,否则不能中断中断。
想象一下需要1分钟才能运行的代码,以及一个拥有16个内核的PC - 现在想象有一百万人试图加载该页面,你可以将工作结果交付给16个人,并且剩下的就是“超时”,或者你可能会使您的Web服务器崩溃,并且不会向任何人提供任人们选择不让他们的Web服务器崩溃,这就是为什么他们永远不允许回调中断其他回调的原因(即使他们尝试过也不会这样 - 调用者永远无法控制回来在前一个调用结束之前进行新的调用.. 。)