2

我在工作中开发的项目有问题。它是一个多线程应用程序。我将 Moose 用于面向对象编程,将 ONE::Timer 用于计时器。我认为我没有很好地使用它,因为我的子程序从未被调用过。基本上,这是我的代码:

sub add {
    my ($self, $bot) = @_;
    my $provision_object = $bot->provision->new;
    $provision_object->compute;
}

我的计算方法如下所示:

sub compute {
    <A couple of line code...>
    ONE::Timer->at($time1, sub { <computations1> });
    ONE::Timer->at($time2, sub { <computations2> });
}

time1time2包含一个时间戳。由于我的脚本是一个服务器(所以它永远不会完成),我确信这些时间是在脚本结束之前达到的。time1after和time2seconds调用的两个子程序永远不会被调用。在该方法的文档ONE::Timer->at,它说:

如果你存储返回值,它就充当一个守卫——如果它被破坏,那么计时器就会被取消。

这就是为什么我不存储对方法的调用的返回值。我在这里错过了什么吗?

非常感谢任何答案;)

4

1 回答 1

2

所以,ONE 是一个事件循环*,所以你必须在某个时候进入循环。通常你会通过调用进入你的事件循环ONE->loop()

在您的事件侦听器之一调用 之前,调用ONE->loop()不会返回ONE->stop()

一种选择是将您的代码包装在一个收集块中,例如:

use ONE qw( Collect );
collect {
    # The main body of your program
};

Collect 只会在您的所有事件都触发一次后返回。

如果你想要绿色线程,也就是说,如果你想让你的事件监听器在没有进一步干预的情况下有效地异步运行,那么编写你的程序:

use EV; # Optional, but everything is better with it
use Coro;
use ONE;

async {
    # Put the body of your program here
    # In order for Coro to trigger and execute your 
    # event handlers, you'd need to be blocking on 
    # IO somewhere in here.

    ONE->stop(); # Call when you want your program to exit
};

ONE->loop();

然而,Coro 有自己的警告,你应该在开始之前阅读它。

使用 Github 上的版本,这将是等价的

use EV;
use Coro;
use ONE;

ONE->loop(sub {
    # Your main body
    ONE->stop;
});

* ONE 是 AnyEvent 的包装器,它本身不实现事件循环,而是提供了一个平台,用于在 AnyEvent 周围添加一个非常薄的抽象。

于 2013-04-16T14:44:17.720 回答