マイクロスレッド

そもそもゲームプログラムというのは、
画面上にたくさんあるキャラクターを同時に動かす、
という「マルチスレッド(並列実行)」を要求されるプログラムです。
 
それをシングルスレッドで擬似的に実現したのが
「タスクシステム」なのです。
 
しかし、例えば

  • シューティングのスクリプトを解析しながらタスクを動かす
  • 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以外でマイクロスレッドはどうやって実現するの?」
 
…えーっと、わかりません(´Д`;
とりあえず、以下の書籍が参考になりますよー、ということで、、、。

でした。