coro学习-击鼓传花

这个是协程的经典例子。

之前有一篇erlang和stackless比较的文章有详细介绍。

用perl的coro实现了一下。

程序没有很好地优化架构,不过便于阅读。

#!/usr/bin/env perl
#coro测试程序testcoro11.pl
#perl版的击鼓传花(erlang和stackless的经典例子)
#由n个节点组成一个环状网络,在上面传送共m个消息。 
#将每个消息(共m个),逐个发送给1号节点。 
#第1到n-1号节点在接收到消息后,都转发给下一号节点。 
#第n号节点每次收到消息后,不再继续转发。 
#当m个消息都从1号逐个到达第n号节点时,认为全部处理结束。
#每次执行时设定n=300,m=10000
use strict;
use Coro;

my $n=$ARGV[0];
if(not defined $n){
	$n=300;
};
my $m=$ARGV[1];
if(not defined $m){
	$m=10000;
}

#创建channel
my @ch;
foreach my $i (1..$n){
	$ch[$i]= new Coro::Channel;
}
#用于结束
my $result=new Coro::Channel;

#创建节点(协程)
my @coro;
foreach my $i (1..$n){
	push @coro , async {
		 #$Coro::current->{desc} = $i;  #给协程起个名字
		 while () {
		   my $msg = $ch[$i]->get; # read msg
		  &Debug("node $i got msg $msg.\n",0);
		   if($i == $n){
		   	 &Debug("msg $msg reached last node $i.\n",0);
		   	 if($msg == $m){
		   	 	 &Debug("final msg send back.\n",0);
		   	 	 $result->put ($msg);
		   	 }
		   }else{
		    &Debug("node $i passed msg $msg to next node.\n",0);
		    $ch[$i+1]->put ($msg);
		   } 
		   #if($msg >= $m){
		   #	last;
		   #}
		 } 
	}
}



#初始化消息
foreach my $j (1..$m){
	 $ch[1]->put ($j);
	
	 &Debug("send msg $j to node 1.\n",0);
	 
}

#等待结束消息
my $msg=$result->get;
&Debug("received final msg $msg.\n",1);

sub Debug($$)
{
  my ($msg,$dlvl)=@_;
	my $DEBUGLVL=1;
	if(not defined $dlvl){
		$dlvl=0;
	}
	if($dlvl >= $DEBUGLVL ){#只显示大于显示界别的调试信息
		print $msg;
	}
	return 0;
	
}
实际测试结果,在注释掉Debug函数调用的情况下,相比erlang和stackless还是有不小的差距的。
#-bash-3.00$ time ./tcoro12_ring.pl 30000 100
#received final msg 100.
#
#real    0m31.085s
#user    0m30.965s
#sys     0m0.118s
#-bash-3.00$ time ./tcoro12_ring.pl 100 30000
#received final msg 30000.
#
#real    0m29.439s
#user    0m29.418s
#sys     0m0.019s
#-bash-3.00$

                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值