免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 5575 | 回复: 10
打印 上一主题 下一主题

AnyEvent有个地方无法理解。 [复制链接]

论坛徽章:
3
未羊
日期:2013-11-18 15:17:06酉鸡
日期:2013-12-06 17:07:16天蝎座
日期:2014-06-11 12:37:07
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-08-08 17:03 |只看该作者 |倒序浏览
最近在做一个项目,被某淫推荐用AnyEvent异步解决问题。但是发现各种奇葩的无法理解的语句,其中最特殊的就是这个
AnyEvent->condvar;

   这个东西,我看了下,所有程序都是以下几个步骤。
  1. my $cv = AnyEvent->condvar;
  2. $cv->begin;
  3. $cv->send;
  4. $cv->recv;
  5. $cv->end;
复制代码
这些步骤我很难理解该在哪放。。。

例如我的程序是如此:
  1. #!/usr/bin/perl
  2. use AnyEvent;
  3. use AnyEvent::HTTP;
  4. use AnyEvent::DBI::MySQL;
  5. use Data::Dumper;
  6. use MIME::Base64;
  7. use Parallel::ForkManager;
  8. use String::Random;
  9. my $pm = Parallel::ForkManager->new(10);

  10.         my $cocurrent=10;

  11.         my $cv = AnyEvent->condvar;

  12.         doit() foreach 1..$cocurrent;

  13. sub doit {  
  14.     my $word;  
  15.           my $cv=AnyEvent->condvar;
  16.     $cv->begin;

  17.                    http_test($h->{$key}->{'url'},$h->{$key}->{'id'},$h->{$key}->{'proxy'});

  18.            $cv->end;
  19. }

  20. sub http_test{
  21.   print "进入子模块!\n";
  22.   my ($url,$id,$proxy) = @_;
  23.   
  24.   print "url: $url id: $id\n";
  25.   $cv->begin;
  26.   http_get( $url, sub { _http( $id,@_ )  } );

  27. }
复制代码
请教我该在什么地方放begin 什么地方放end,什么地方放recv?

论坛徽章:
3
未羊
日期:2013-11-18 15:17:06酉鸡
日期:2013-12-06 17:07:16天蝎座
日期:2014-06-11 12:37:07
2 [报告]
发表于 2014-08-08 17:21 |只看该作者
例如以下例子,直接没有输出了。。这个比较简单些。。。
  1. #!/usr/bin/perl
  2. use AnyEvent;
  3. use AnyEvent::HTTP;
  4. use AnyEvent::DBI::MySQL;
  5. use Data::Dumper;
  6. use MIME::Base64;
  7. use Parallel::ForkManager;
  8. use String::Random;
  9. my $pm = Parallel::ForkManager->new(100);


  10. my $cocurrent=10;

  11. my $cv = AnyEvent->condvar;

  12. http_test() foreach 1..$cocurrent;
  13. $cv->recv;

  14. sub http_test{
  15.         $cv->begin;
  16.         http_get( "http://www.baidu.com/", sub { print Dumper @_  } );
  17.         $cv->end;
  18. }
复制代码

论坛徽章:
42
19周年集字徽章-周
日期:2019-10-14 14:35:31平安夜徽章
日期:2015-12-26 00:06:30数据库技术版块每日发帖之星
日期:2015-12-01 06:20:002015亚冠之首尔
日期:2015-11-04 22:25:43IT运维版块每日发帖之星
日期:2015-08-17 06:20:00寅虎
日期:2014-06-04 16:25:27狮子座
日期:2014-05-12 11:00:00辰龙
日期:2013-12-20 17:07:19射手座
日期:2013-10-24 21:01:23CU十二周年纪念徽章
日期:2013-10-24 15:41:34IT运维版块每日发帖之星
日期:2016-01-27 06:20:0015-16赛季CBA联赛之新疆
日期:2016-06-07 14:10:01
3 [报告]
发表于 2014-08-08 17:59 |只看该作者
my $cv = AnyEvent->condvar;代表事件循环开始
$recv就是整个事件循环结束
$begin和$end是一对事务.
比如你要异步取100个网站
那么每个http_get之前begin,回调里面end
全都取完了$recv结束

你看看以前斑竹贴的例子,超清晰
  1. #!/usr/bin/perl

  2. use strict;
  3. use warnings;
  4. use AnyEvent;
  5. use AnyEvent::HTTP;

  6. my $cocurrent = 100;    # 并发数
  7. my @todoList = map { "keyword" . $_ } (1 .. 1000); # 待查询的关键词

  8. my $cv = AnyEvent->condvar;

  9. doit() foreach 1..$cocurrent;

  10. sub doit{
  11.     my $word = shift @todoList;
  12.     return if not defined $word;

  13.     $cv->begin;
  14.     http_get( "http://www.baidu.com/s?wd=$word", sub { done( $word, @_ ) } );
  15. }

  16. sub done {
  17.     my ($word, $content, $hdr) = @_;

  18.     $cv->end();
  19.     print "Search: $word\tStatus: ", $hdr->{Status}, "\n";
  20.     doit();
  21. }

  22. $cv->recv();
复制代码

论坛徽章:
42
19周年集字徽章-周
日期:2019-10-14 14:35:31平安夜徽章
日期:2015-12-26 00:06:30数据库技术版块每日发帖之星
日期:2015-12-01 06:20:002015亚冠之首尔
日期:2015-11-04 22:25:43IT运维版块每日发帖之星
日期:2015-08-17 06:20:00寅虎
日期:2014-06-04 16:25:27狮子座
日期:2014-05-12 11:00:00辰龙
日期:2013-12-20 17:07:19射手座
日期:2013-10-24 21:01:23CU十二周年纪念徽章
日期:2013-10-24 15:41:34IT运维版块每日发帖之星
日期:2016-01-27 06:20:0015-16赛季CBA联赛之新疆
日期:2016-06-07 14:10:01
4 [报告]
发表于 2014-08-08 18:00 |只看该作者
回复 2# 墨迹哥


    你这个end明显放错位置了

论坛徽章:
3
未羊
日期:2013-11-18 15:17:06酉鸡
日期:2013-12-06 17:07:16天蝎座
日期:2014-06-11 12:37:07
5 [报告]
发表于 2014-08-08 19:01 |只看该作者
回复 4# laputa73


    版主写的那个确实很精细。。。。当时没很细的分析,这是自己的一个毛病。

    刚才自己摸索,写了个单例DEMO就成功了,牢牢记住了。。

    PS: 你最近也很忙挖?

论坛徽章:
42
19周年集字徽章-周
日期:2019-10-14 14:35:31平安夜徽章
日期:2015-12-26 00:06:30数据库技术版块每日发帖之星
日期:2015-12-01 06:20:002015亚冠之首尔
日期:2015-11-04 22:25:43IT运维版块每日发帖之星
日期:2015-08-17 06:20:00寅虎
日期:2014-06-04 16:25:27狮子座
日期:2014-05-12 11:00:00辰龙
日期:2013-12-20 17:07:19射手座
日期:2013-10-24 21:01:23CU十二周年纪念徽章
日期:2013-10-24 15:41:34IT运维版块每日发帖之星
日期:2016-01-27 06:20:0015-16赛季CBA联赛之新疆
日期:2016-06-07 14:10:01
6 [报告]
发表于 2014-08-10 08:26 |只看该作者
回复 5# 墨迹哥


    是很忙.
    都没啥时间自己学习了.

论坛徽章:
3
未羊
日期:2013-11-18 15:17:06酉鸡
日期:2013-12-06 17:07:16天蝎座
日期:2014-06-11 12:37:07
7 [报告]
发表于 2014-08-12 14:02 |只看该作者
回复 6# laputa73


    我发现这个AnyEvent多进程操作总有问题,有得时候会直接挂起。不知道为啥。

    中间总会有停顿,我不太理解之前PY所说的用一个“主进程”挂起,然后去控制的原理。

    你理解不?  

    ------
   
    最近我也忙乎极点,天天加班就在倒腾这玩意。蛋疼ing~

    MCshell童鞋被我忽悠过来上班了撒。。- - # 可是他老忙架构的事情,木有时间和我一块研究。。。

    你私信你Q给我呗,有空余时间就一起折腾下。。

论坛徽章:
42
19周年集字徽章-周
日期:2019-10-14 14:35:31平安夜徽章
日期:2015-12-26 00:06:30数据库技术版块每日发帖之星
日期:2015-12-01 06:20:002015亚冠之首尔
日期:2015-11-04 22:25:43IT运维版块每日发帖之星
日期:2015-08-17 06:20:00寅虎
日期:2014-06-04 16:25:27狮子座
日期:2014-05-12 11:00:00辰龙
日期:2013-12-20 17:07:19射手座
日期:2013-10-24 21:01:23CU十二周年纪念徽章
日期:2013-10-24 15:41:34IT运维版块每日发帖之星
日期:2016-01-27 06:20:0015-16赛季CBA联赛之新疆
日期:2016-06-07 14:10:01
8 [报告]
发表于 2014-08-12 14:53 |只看该作者
anyevent是一个事件模型。不知道你有没有学过从前c语言和汇编里面的中断。
多数AE的模块是单进程的
对于单进程程序,正常情况下程序顺序执行,如果碰到阻塞,比如查询数据库,下载网页操作。
一种思路就是等待,等完成了继续,这种显然效率很低。
另一种思路是挂起阻塞的函数, 申请一个回调事件,先处理其他的函数,等慢函数执行完了,通过回调事件,重新获取执行权。这样就实现了无阻塞。
协程coro可以看作是事件模式的一个变种的封装。
因为整个程序其实还是单进程操作,所以这里的关键是在于阻塞的操作时可以被挂起,也就是说是支持事件回调的(EV,AE等)
如果你写个sleep(),那它本身会把整个线程全部阻塞,包括事件调度,就起不到并行的效果了。看起来就是整个进程挂住了。
其他的比如socket操作,文件操作,mysql操作等等,都可能有这个问题,必须换成支持事件的版本。

另外,AE有些模块不是单进程的 ,而是通过多进程实现的。

论坛徽章:
3
未羊
日期:2013-11-18 15:17:06酉鸡
日期:2013-12-06 17:07:16天蝎座
日期:2014-06-11 12:37:07
9 [报告]
发表于 2014-08-13 16:01 |只看该作者
回复 8# laputa73


    目前是理解了,可能操作起来还需要点时间研究下。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
10 [报告]
发表于 2014-08-13 22:25 |只看该作者
这就是几个同步原语,要理解这个模型,理解了之后再用。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP