# 追記: 2010 19 Feb - このコード何回も書くの面倒くさくなったので、
# CPANにモジュールアップロードしてしまいました
# http://search.cpan.org/dist/AnyEvent-FIFO/
コールバック$cbの最初の引数をguard変数にしておき、キューの1スロットを使用している間はこのguard変数をundefしないようにしておく感じです。
use strict; use AnyEvent; use AnyEvent::Util; my @q; # ~_~Z~[~A~B~C~C~C~P~C~C~B~B~R~E~B~L~A~A~J~A~O~A~A~S~B~M my $ACTIVE = 0; # ~O~\~A使~T中~B~C~C~C~C~H my $MAX_ACTIVE = 1; # ~\~@大~U~@~K~A~B~C~C~C~P~C~C~B~B~R~@~L~P~L~Y~B~@~M~A~L~A~F~A~K~H~B~B~A~B~M~B~S~\~S~A~P~L~Y~B~A~X~B~C~A~A~D~B~H~A~I sub drain_queue { while ( @q && $ACTIVE < $MAX_ACTIVE ) { if (my $cb = shift @q) { $ACTIVE++; $cb->( AnyEvent::Util::guard { $ACTIVE--; drain_queue(); }); } } }
デモ程度に 1から10までの数字を(最低)0.5秒あけてから表示するコード:
my $cv = AE::cv; # XXX - 12/1: ~B~H~A~O~B~H~A~O~@~C~A~H~A~_~B~I~A~S~A~S~Abegin()/end()使~A~F~A~A~S~B~M~A| ~A~A~_~A~A # 修正~A~W~A~A~J~A~D~A~_ for my $x (1..10) { $cv->begin; push @q, sub { my $guard = shift; my $w; $w = AE::timer 0.5, 0, sub { undef $guard; undef $w; warn $x; $cv->end; }; }; } drain_queue(); $cv->recv;
これ以外の実装の仕方もあるんだけれども、これだと次のqueue popとかを自前で呼ぶ必要がないのが素敵です。
カテゴリ
日常トラックバック(1)
このブログ記事に対するトラックバックURL: http://mt.endeworks.jp/cgi-bin/mt-tb.cgi/2417
» 昨日知ったことより: [Perl]AnyEvent::HTTP の同時接続数制限を理解する修行、その1
AnyEvent::HTTP では、同一ホストに対して同時に接続する数を制限している。セマフォを使うのではなく、単なるカウンタを使っていることらしいことが、AnyEvent + Coro での並行ダウンローダの習作 その 2 - 昨日知ったことに引用したコードからわかった。しかし、その意味 読む


コメントする