[SikiLanguage] [式鬼言語航海日誌] 2007-09-09
2007/09/09_000000ということで、今日はFiberを実装してみました。全てのプロセスのベースにするつもりですので、けっこう重要なところですね。
「ふぁいばあ?」
マイクロスレッドとかコルーチンとか言われるものですね。(ルーチンが自発的に)処理を一時中止することのできる特殊なルーチンです。
- Wikipedia:コルーチン
- 魅力的なPython: Pythonジェネレーターで「無重量スレッド」を実装する
- 東方弾幕風:マイクロスレッド講座
- Schi Heil と叫ぶために:プロセス、スレッド、ファイバ、タスク、ジョブ、違いを整理してみよう
あたりですかね。意外と解説が少ないようです。
関数型言語ですと「継続」を扱えると色々と便利ですが、構造化プログラミングですとコルーチンが使えると色々と便利になります。関数オブジェクトとかクロージャとかと組み合せると強力ですね。また、プロセスやスレッドなどと比べて呼び出すときの負担が軽いというメリットがあります。
「ふうン」
で、式鬼言語では、このFiberを実行の基本的な挙動にしようかと考えています。で、プロセスやスレッドはFiberから派生させる形で実装する……と。現にメインプロセスはFiberから派生させて実装しました。
詳細はこれから詰めですが、なかなか良い感じです。
「いっそのこと、クロージャとかデリゲータとかもこいつで作っちまうのも良さそうだね」
とりあえず使ってみましょう。
{!'test'}.execute
{!~~}の部分がFiberです。Fiberは.executeというメッセージを送り付けて実行することができます。
ここでは簡単に文字列'test'を戻すというFiberですね。
と、言っても、Fiberは元のプロセスからは切り離されます。戻り値はFiber自身が持っていて、呼び出し元のプロセスには戻しません。
そのため、このソースを実行すると、
- Rootの受け取った戻り値: Fiber
- Fiberの受け取った戻り値: 'test'
ということ結果になります。ですので、Fiberの実行結果を使いたいと思ったら、Fiberに.executeを送った後に、Fiber自身から結果を引っ張り出す必要があります。
「ちょっと面倒だねぇ」
まあ、派生型として呼び出し元に戻り値を返すFiberも実装しようかと考えていますので、必要だったらそっちを使うことにしましょう。
ついでに言うと、Fiber自体は破壊的実行です。一度実行したらそれでお仕舞いです。
例えば、
{!'test' ..append} 'test2' ..pack .execute 'test3' ..pack .execute
というソースがあったとします。これは
- Fiberに'test2'という文字列をFiberのスタックに積んで一度実行し、次に'test3'という文字列をFiberのスタックに積んで再度実行する
- Fiberは、スタックに積んである文字列に'test'という文字を結合する
という意味です。
Fiber自体は一度実行されたらお仕舞いですので、これは 'test2'に'test'を結合して'test2test'にする 二回目の.executeでは、Fiberはすでに終了しているので何もしない。'test3'はそのまま
という結果になります。こんな感じですね。
Root::tail (Fiber) (Fiber)::tail 'test2test' 'test3'
制作・著作: 野分(nowake) at fiercewinds.net (Creative Commons 表示-継承 2.1 日本)