マイクロスレッド
そもそもゲームプログラムというのは、
画面上にたくさんあるキャラクターを同時に動かす、
という「マルチスレッド(並列実行)」を要求されるプログラムです。
それをシングルスレッドで擬似的に実現したのが
「タスクシステム」なのです。
しかし、例えば
- シューティングのスクリプトを解析しながらタスクを動かす
- AIで経路を探索しながらタスクを動かす
といった処理を求められる場合、
「タスクシステム」では実行関数が途中で制御を返すことが難しいため、
実装が困難になってしまいます。
かといって、マルチスレッドは、
- CPUパワー・メモリ領域を大量に使用する
- 排他制御が大変
というデメリットがあり、これはこれで大変です。
そこで生まれた(かどうかは知らないのですが…)のが、
マイクロスレッドです!
マイクロスレッドとは、
例えば、ゲームループの中で、ある処理Aを実行します。
しかし、その処理は時間がかかるので、進捗率10%ぐらいでゲームループに制御を返します。
そしてそのほかの処理が完了したところで、もう一度処理Aを呼び出します。
処理Aは進捗率10%のところから再開します。
といったように、平行して処理をおこなうというのが、「マイクロスレッド」です。
「え?ようは処理Aの実行履歴を持たせて、そこから再開することでしょ?」
はい、タスクシステムではそういった処理になると思います。
しかし、例えばPythonでは言語的に「マイクロスレッド」(正確にはジェネレーター)
をサポートしているので、以下のように記述することができます。
# MircoThread1 def printNum(): for i in range(3): print i yield None # MircoThread2 def printChar(): for c in ["a", "b", "c"]: print c yield None # Execute MicroThread def execthread(g, gen): try: g.next() except StopIteration: g = gen g.next() return g # Main g1 = printNum() g2 = printChar() for i in range(3): g1 = execthread(g1, printNum()) g2 = execthread(g2, printChar())
yieldが関数の実行をサスペンド(休止)しています。
関数内にyieldがあると、その関数は他の関数とは異なるメモリ構造を持ちます。
そのため、このような使い方をします。
実行結果は以下のようになります。
0 a 1 b 2 c
どうでしょうか。
printNum()とprintChar()を同時に実行しているのが分かると思います。
「なるほど。ではPython以外でマイクロスレッドはどうやって実現するの?」
…えーっと、わかりません(´Д`;
とりあえず、以下の書籍が参考になりますよー、ということで、、、。
でした。