加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

perl – 为什么AnyEvent计时器观察者必须在其回调中被解雇?

发布时间:2020-12-15 21:44:16 所属栏目:大数据 来源:网络整理
导读:在尝试理解AnyEvent的过程中,我创建了两个定时器,每次定时器都会被触发屏幕.最初都没有工作.但是在 Joshua Barratt’s timer example之后,我发现如果我没有取消定时器的观察者变量,那么定时器的回调根本不会触发.为什么会这样?我怀疑它与范围在perl和/或Any
在尝试理解AnyEvent的过程中,我创建了两个定时器,每次定时器都会被触发屏幕.最初都没有工作.但是在 Joshua Barratt’s timer example之后,我发现如果我没有取消定时器的观察者变量,那么定时器的回调根本不会触发.为什么会这样?我怀疑它与范围在perl和/或AnyEvent中的工作方式有关.

这是我的示例程序:

#!/usr/bin/perl

use AE;

my $cv = AE::cv;

sub func1 {
   my $spoke = 0;
   my $t1; $t1 = AE::timer 0,1,sub { 
         print "Timer 1 Firedn";
         if($spoke++ > 5) {
            print "Timer 1 Donen";
            undef $t1;
         }   
      };  
      print "Timer 1 startedn";
}

sub func2 {
   my $spoke = 0;
   my $t2; $t2 = AE::timer 0,sub { 
         print "Timer 2 Firedn";
         if($spoke++ > 5) {
            print "Timer 2 Donen";
            #undef $t2;
         }   
      };  
      print "Timer 2 startedn";
}

func1();
func2();

$cv->recv;

原样,我的代码返回:

Timer 1 started
Timer 2 started
Timer 1 Fired
Timer 1 Fired
Timer 1 Fired
Timer 1 Fired
Timer 1 Fired
Timer 1 Fired
Timer 1 Fired
Timer 1 Done

如果我取消注释undef $t2;行,定时器2的回调被触发,我得到这个:

Timer 1 started
Timer 2 started
Timer 1 Fired
Timer 2 Fired
Timer 2 Fired
Timer 1 Fired
Timer 1 Fired
Timer 2 Fired
Timer 2 Fired
Timer 1 Fired
Timer 1 Fired
Timer 2 Fired
Timer 2 Fired
Timer 1 Fired
Timer 1 Fired
Timer 1 Done
Timer 2 Fired
Timer 2 Done

解决方法

你必须保持守护对象($t1的值)存活.如果对它的所有引用都消失了,它将被销毁,并取消该事件.

在闭包中引用$t1会导致闭包捕获它,使其保持活动状态,直到它在func结束时正常死亡.

如果你想捕获一个你不需要的变量,你可以使用

$t2 if 0;   # Keep timer alive until process exit.

这是一个闭包的简单例子:

sub make_closure {
   my ($x) = @_;
   return sub {
      print("$xn");
   };
}

my $f1 = make_closure("Hello,World!");
my $f2 = make_closure("Allo,Jeune Renard!");

$f1->();
$f2->();

注意闭包(anon sub)如何捕获当时存在的$x?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读