Coro::State - 現在の実行状態を保存しておける箱
Coroっていうモジュールがあります。Coroutine っていう概念を理解してないのもあり、 dmakiさんの記事で、なんとなく、 非同期でいろいろ出来るようになるモジュールなんだろうな、っていうくらいにしか考えて 無かったんですが、本質的にはちょっとイメージが違ったっぽいっす。
全然間違っているかもだけど、現在の僕の理解を書いてみます。
Coro.pm のソースを見てると、Coro::Stateをベースクラスにしてます。 このCoro::State、ドキュメント読んでても英語が不得意なせいもあり、よく分からなかったんですが、 いろいろいじってるうちに、なんとなく、「現在の実行状態(レキシカル変数や、関数スタック)を保存 しておける箱」っていうのが見えてきました。
といっても意味分からないっすね。
とりあえずサンプルコード
use Coro::State;
$::main = Coro::State->new();
$::sub = Coro::State->new(sub{
print "in sub.\n";
$::sub->transfer($::main);
print "in sub again.\n";
$::sub->transfer($::main);
});
print "in main.\n";
$::main->transfer($::sub);
print "back to main.\n";
$::main->transfer($::sub);
print "back to main again.\n";
__END__
こんな感じ。実行すると、
in main.
in sub.
back to main.
in sub again.
back to main again.
と表示されました。
順を追って説明します。まず
$::main = Coro::State->new();
で空の箱を作ります。 この中に実行状態を保存するわけですが、Coro::Stateでは、状態の保存と同時に別の Coro::State に処理を移す必要があります。というわけで、別のCoro::Stateを作ります。 空のCoro::Stateには飛ばせないので、作成時に実行状態を与えてあげます。
$::sub = Coro::State->new(sub{ ... });
こうすることで、「引数の sub{ ... } 実行直前」という状態を持ったCoro::Stateが作成されます。 一個目のprint文を実行した後:
$::main->transfer($::sub);
これで、$::main に現在の実行状態を保存しつつ、$::sub に処理が移り、 $::subが実行開始されます。
"in sub." を表示した後:
$::sub->transfer($::main);
$::sub に現在の実行状態、つまり「無名関数の一つ目のprint文の後まで進んだ」 という状態が保存されつつ、 $::main に処理が戻り、transfer した直後から処理が再開され、 "back to main." を表示、以下続く。
とかそんな感じです。
Stateを複数作って、処理を途中で投げ出してあらぬところに飛んでいったり、またあらぬところから 処理が戻ってきたりできちゃいます。goto でも似たようなことが出来そうだけど、レキシカル変数や スタックが保存されているのが大きな違い。変数が共有されるPerlインタプリタを複数作って、その 間を行ったり来たりする感じに近いっぽい。
Coro.pm は Coro::State を隠蔽して、Coro::State オブジェクトの管理を自動化しているです。
ところで、スレッド等と違って同時実行されるわけではなくて、あくまで一つが動いている間は、 他は止まっているってドキュメントに書いてあるのに、なんで非同期処理が出来るんだ? って 思ったら、これとイベント系のモジュール(see Coro::AnyEvent)を組み合わせると非同期プログラミングが楽に出来るぜって話なのかと。 それにはイベント系のモジュールを理解しないと分からないっぽいので勉強する時間があったら。
なんでCoroに手を出したかって言うと、use Perl; の記事 見て、Generator は、 Coro で出来るよんって書いてあって、何ですかそれ?ってな具合です。
CPANに Coro::Generator っていうのが上がってて、 なるほどねーって感じだったんだけど、バグっぽかったので、一から書き直してAttribute::Generator を 作ってみたのでした。
けど遅くては意味ないのです><
トラックバック(0)
このブログ記事を参照しているブログ一覧: Coro::State - 現在の実行状態を保存しておける箱
このブログ記事に対するトラックバックURL: http://www.fs-output.com/rintaro/mt/mt-tb.cgi/27

コメントする