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? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |