# 追記: 2010 19 Feb - このコード何回も書くの面倒くさくなったので、
# CPANにモジュールアップロードしてしまいました
# http://search.cpan.org/dist/AnyEvent-FIFO/

まぁ考えてみれば単純な話ですけど、いわゆるGuardを使うとよいです。参考はAnyEvent::HTTP

コールバック$cbの最初の引数をguard変数にしておき、キューの1スロットを使用している間はこのguard変数をundefしないようにしておく感じです。
   use strict;
   use AnyEvent;
   use AnyEvent::Util;

   my @q; # 実際にコールバックを入れておくところ
   my $ACTIVE = 0; # 現在の使用中スロット
   my $MAX_ACTIVE = 1; # 最大何個のコールバックを「同時」に行うか(もちろん本当に同時じゃないよ!)

  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: よくよく考えたらここはbegin()/end()使うところだったので
# 修正しておいた
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

AnyEvent::HTTP では、同一ホストに対して同時に接続する数を制限している。セマフォを使うのではなく、単なるカウンタを使っていることらしいことが、AnyEvent + Coro での並行ダウンローダの習作 その 2 - 昨日知ったことに引用したコードからわかった。しかし、その意味 読む

コメントする

筆者

daisuke - a.k.a. "lestrrat", Perl hacker at Livedoor Inc, Japan Perl Association 代表理事

このブログ記事について

このページは、Dが2009年11月24日 14:01に書いたブログ記事です。

ひとつ前のブログ記事は「人生の気合いが表れるゲームです。」です。

次のブログ記事は「Perlな人たち、どこにいるの」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

Powered by Movable Type 4.1