你如何睡觉"在AnyEvent回调中没有暂停整个脚本?

时间:2015-01-15 18:28:04

标签: perl asynchronous sleep anyevent

我特别使用AnyEvent :: Inotify :: Simple(使用EV作为后端)来监视文件事件。所以我有一个处理程序回调,在特定情况下,我需要在继续之前“暂停”。 sleep显然会停止所有事情(因此在完成sleep之后才会处理其他事件),所以我尝试使用alarm但是如果出现再次设置警报的相同情况,原始警报(因此其$SIG{ALRM}子)被忽略,只运行“新”警报。

#sleep-based approach (definitely a no-go)
sub handler {
    my ( $self, $event, $file ) = @_;
    #do some stuff
    ...
    if( $some_condition_exists ) {
        sleep(3);
        #now that we've waited, if some change occurred then do stuff
        if ( $new_change_occurred ) {
            #do some new stuff
        }
    }
    return;
}

#alarm -based approach (still a no-go when callback is called again while original alarm is still counting down)
sub handler {
    my ( $self, $event, $file ) = @_;
    #do some stuff
    ...
    if( $some_condition_exists ) {
        $SIG{ALRM} = sub {
             #now that we've waited, if some change occurred then do stuff
             if ( $new_change_occurred ) {
                 #do some new stuff
             }
        }
        alarm(3);
    }
    return;
}

任何建议都会受到赞赏吗?我只需要一种方法来使回调暂停,同时继续异步处理新的inotify事件。

1 个答案:

答案 0 :(得分:1)

使用AnyEvent :: timer时,请确保跟踪它返回的保护对象。我通常将它们存储在全局中。

如果将其分配给超出范围的变量,则计时器将被取消。

my $guards;

sub handler {
    my ( $self, $event, $file ) = @_;
    #do some stuff
    ...
    if( $some_condition_exists ) {
        $guards->{$file} = AE::timer 3,0,sub {
             #now that we've waited, if some change occurred then do stuff
             if ( $new_change_occurred ) {
                 #do some new stuff
             }
        };
    }
    return;
}