tokuhirom's Blog

Coro and AnyEvent as good friend

Coro と AnyEvent はどういう関係なのかを整理しておく。

Coro → AnyEvent

Coro は AnyEvent に依存している(requires 扱い)。

Coro は

  • ファイル/ソケット/etc の 読みこみ/書き込み待ち のとき
  • タイマを稼働させるとき

などに AnyEvent を内部的につかっている。

ただし、Coro を純粋に co-routine としてつかう場合には Coro::AnyEvent は必要ないです。async { }->join() するだけなら必要ない。
ただ、Coro::* 系のモジュールはたいがいが Coro::AnyEvent つかってるので、co-routine としてつかう場合には AnyEvent がほとんど必須だとおもってまちがいないですます。

AnyEvent → Coro

AnyEvent をイベントフレームワークとしてつかうだけならば、Coro をつかう必要はなく、単体で利用可能。単体ならば依存モジュールがなく PP なので extlib/ などに同梱することも容易だ。

ただし、Coro をつかうと AnyEvent 単体で書くよりも楽にかけるケースがある。それは今おもいつく限りだと以下の2つだ。

  • CPU インテンシブな処理を書く場合
    • 要所要所に cede; と書くだけで他のスレッド/イベントに処理をまわせるので楽
    • コールバックなどつかわずに書きたいことをスラスラかける
  • ファイルハンドルの操作を簡単にかきたい場合
    • push_read とか push_write とかめんどいじゃん。

基本的にはいずれも Event base でかけないことはないのだが、Coro をつかうことでより簡単にかくことができる。

たとえば、こんな処理は AnyEvent だけで書くと結構めんどいですね。

use Coro;
use Coro::AnyEvent;
use Coro::Handle;

async_pool {
  my $out = unblock STDOUT;
  for my $i (0..10000) {
     $out->write("$i\n");
     cede;
  }
};

# any server code...

AnyEvent->condvar->recv;