免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4568 | 回复: 4

请教AnyEvent [复制链接]

论坛徽章:
1
双子座
日期:2013-11-06 17:18:01
发表于 2013-12-25 15:31 |显示全部楼层
本帖最后由 seufy88 于 2013-12-25 16:06 编辑

最近在看AnyEvent
在讲解到$cv->recv时,有几句话不是很懂。
$cv->recv
Wait (blocking if necessary) until the ->send or ->croak methods have been called on $cv, while servicing other watchers normally.

You can only wait once on a condition - additional calls are valid but will return immediately.

If an error condition has been set by calling ->croak, then this function will call croak.

In list context, all parameters passed to send will be returned, in scalar context only the first one will be returned.

Note that doing a blocking wait in a callback is not supported by any event loop, that is, recursive invocation of a blocking ->recv is not allowed and the recv call will croak if such a condition is detected. This requirement can be dropped by relying on Coro::AnyEvent , which allows you to do a blocking ->recv from any thread that doesn't run the event loop itself. Coro::AnyEvent is loaded automatically when Coro is used with AnyEvent, so code does not need to do anything special to take advantage of that: any code that would normally block your program because it calls recv, be executed in an async thread instead without blocking other threads.

Not all event models support a blocking wait - some die in that case (programs might want to do that to stay interactive), so if you are using this from a module, never require a blocking wait. Instead, let the caller decide whether the call will block or not (for example, by coupling condition variables with some kind of request results and supporting callbacks so the caller knows that getting the result will not block, while still supporting blocking waits if the caller so desires).

You can ensure that ->recv never blocks by setting a callback and only calling ->recv from within that callback (or at a later time). This will work even when the event loop does not support blocking waits otherwise.

(1)》Note that doing a blocking wait in a callback is not supported by any event loop
这句是指callback最好是不要有会 block的语句

(2)》Not all event models support a blocking wait
这句是讲什么,“不是所有事件模块都支持BLOCK WAIT”?
请问这里的block wait是指 $cv->recv吗

(3)》so if you are using this from a module, never require a blocking wait. Instead, let the caller decide whether the call will block or not
=》求说明

(4)》You can ensure that ->recv never blocks by setting a callback and only calling ->recv from within that callback (or at a later time). This will work even when the event loop does not support blocking waits otherwise
这句就比较绕了。
你可以通过这样的方式来确保->recv不会block: 设定一个callback,并在这个callback里只调用->recv.


作为我这个新手来讲,都是在main programe里显示调用$cv->recv来开启loop的。
试验了一下,在callback里调用$cv->recv好像“不起作用”,event loop不会开启。那第(4)句中的方法,->recv是不会BLOCK了,但EVENT LOOP会启动起来么?

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2013-12-25 20:09 |显示全部楼层
1. 作者哪说“最好是不要有”了?。原话中显然没有这个意思。callback中不能有阻塞等待
2. 这段的语言环境就是在说recv,blocking wait指的就是recv
3. 他这是再说写事件模块呢,如果是anyevent的使用者,可以忽略这块。
4. 这句的意思是,recv是阻塞的,但你可以用->cb建立一个回调,这样你就不必等这个recv了。这有点像很多的->recv在一起不会阻塞

论坛徽章:
1
双子座
日期:2013-11-06 17:18:01
发表于 2013-12-26 09:05 |显示全部楼层
py 发表于 2013-12-25 20:09
1. 作者哪说“最好是不要有”了?。原话中显然没有这个意思。callback中不能有阻塞等待
2. 这段的语言环境 ...

4. 这句的意思是,recv是阻塞的,但你可以用->cb建立一个回调,这样你就不必等这个recv了。这有点像很多的->recv在一起不会阻塞
》这句话还是没明白,能否举例说明一下。

论坛徽章:
1
双子座
日期:2013-11-06 17:18:01
发表于 2013-12-26 10:29 |显示全部楼层
回复 2# py
》4. 这句的意思是,recv是阻塞的,但你可以用->cb建立一个回调,这样你就不必等这个recv了。这有点像很多的->recv在一起不会阻塞
是指如下描述吗?
$cb = $cv->cb ($cb->($cv))
This is a mutator function that returns the callback set and optionally replaces it before doing so.

The callback will be called when the condition becomes "true", i.e. when send or croak are called, with the only argument being the condition variable itself. If the condition is already true, the callback is called immediately when it is set. Calling recv inside the callback or at any later time is guaranteed not to block.

具体到代码就是如下的方案1?

  1. use AnyEvent;
  2. use AnyEvent::Handle;

  3. my $cv = AnyEvent->condvar;

  4. my $io_watcher = AnyEvent->io(
  5.         fh => \*STDIN,
  6.         poll =>'r',
  7.         cb => sub {
  8.                 warn " io event <$_[0]>\n";
  9.                 chomp(my $input = <STDIN>);
  10.                 warn "read:$input\n";
  11.                 $cv->send if $input=~/^q/i;
  12.         }
  13.      );

  14. my $time_watcher = AnyEvent->timer(after=>1,interval=>1,
  15.                         cb=> sub{
  16.                         warn "timeout\n";
  17.                         });

  18. #方案1
  19. #$cv->cb(sub {shift->recv;undef $time_watcher});

  20. #方案2
  21. #$cv->recv;

  22. # do something else.....


  23. #end of program

复制代码
针对上述代码,有个疑问,如果#do something else没有任何实质内容。将->recv放置于callback,而非main program的话。
是不是整个program就马上退出了?事件“来不急”触发

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2013-12-26 19:17 |显示全部楼层
我觉得他说的不是这个意思。

而是两个事件(两个cv),cv1的recv如果直接写在cv2的callback中就会发生阻塞报错,这个时候就要把cv1用cb包裹起来,从而避免阻塞报错。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP