Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env perl
- use strict;
- use warnings;
- use Coro;
- use Perl6::Say;
- # とりあえず分かったことをまとめてみた
- # 間違ってるかもしれないので教えてくれるとうれしい
- #
- # NOTE: コルーチン(継続?)の性質上読む場所が二転三転します
- # cedeは以下のことを行うもの
- #
- # 1. 現在の継続をエンキュー (push)
- # - これをするのが$Coro::current->ready()
- # 2. 先頭の継続をデキュー (unshift)
- # - これがschedule()
- sub printit {
- my $s = shift;
- # 1回目のcedeでは
- # キュー: [<async>, <main>]
- # push: [<async>, <main>], <printit>
- # unshift: <async> <= [<main>, <printit>]
- # そして2個目の<async>に飛ぶ。
- #
- # そうするとまたprintit()が呼ばれているので
- # この2回目のcedeでは
- # キュー: [<main>, <printit>]
- # push: [<main>, <printit>], <printit>
- # unshift: <main> <= [<printit>, <printit>]
- # となって、<main>に飛ぶ。
- cede;
- # ここでエンキューされた2つの<printit>がようやく処理される。
- #
- # 1回目:
- # 1個目の<printit>が継続されているのでキューの中身は
- # [<printit>, <main>]
- # 2回目:
- # 2個目の<printit>が継続中。キューの中身は
- # [<main>]
- print $s;
- # <main> <= []
- # <main>に戻る。
- }
- # [<async>]
- async { printit "hello, " };
- # [<async>, <async>]
- async { printit "wolrd\n" };
- # cedeはこのキューに対して現在の継続(この場合メイン継続)
- # をpushし、先頭のキューをunshiftする。
- # キュー: [<async>, <async>]
- # push: [<async>, <async>], <main>
- # unshift: <async> <= [<async>, <main>]
- # そして取り出された1回目の<async>(つまりprintit())に飛ぶ。
- cede;
- # キュー: [<printit>, <printit>]
- # push: [<printit>, <printit>], <main>
- # unshift: <printit> <= [<printit>, <main>]
- # <printit>に飛ぶ。
- cede;
- # キュー上に<main>しかないので<main>に戻り終了。
- # この時キュー上は
- # []
- #
- # キューに継続が残ってても処理されず破棄される。
- # 逆にキューに継続が残っていない場合にscheduleすると
- # アンダーフローを起こしてエラーになる。
- # 「FATAL: deadlock detected at ...」
- # NOTE: やめて!
- # schedule;
Add Comment
Please, Sign In to add comment