Next: Up: Previous:

Fork-Join

figure226

図3.8に示された簡単なfork-joinプロトコルを考えてみよう. マスタスレッド(master)は多数の子スレッド (task)をforkし, 全ての作られたスレッドが終わるのを 待つ. マスタと全ての子は終わっていないタスクの 数を保持するカウンタを共有する. マスタは子スレッドを ただ単にCの手続き task をループ内で呼ぶことで fork し, 完了を待つために join_children を呼び出す. 各タスクはここでは重要ではない何かの計算を行ない, 計算中にブロックするかもしれず, そして, 終了したときには, 最終的には signal_finish を呼び出すだろう. 結果として, マスタが join_children を 試みたときにいくつかのタスクがまだ未完了であるときに マスタはブロックする.

基本的には2つのシナリオがある. もし実際にブロックする子が ないときには, task への各手続き呼び出しは マスタに返ることなしに, signal_finish を 呼び出す. signal_finish への全ての呼びだしは単純に カウンタを一つづつ減らすだけである. マスタは join_children のカウンタをチェックし カウンタがすでにゼロであるのを発見し, そのまま実行を継続する. 一方, もし子のどれかがブロックしたときには, マスタが join_children によってカウンタを チェックしたときに, カウンタはゼロでないかもしれない. その場合は, マスタはヒープコンテキストを確保し, そのカウンタにコンテキストを書き込み, 自分を ブロックさせるために switch_to_parent を 呼び出す. 最後の子が signal_finish を呼ぶ時, その子はカウンタの中にコンテキストが書かれているのを 発見し, マスタを再開するだろう.

この例は単純なケースにおいて, StackThreads のプリミティブ上でどのように同期オペレーション(例えば, コンテキストスイッチを起動するオペレーション)を設計, 実装するのか を解説している. この例では, join_children は同期オペレーションである. 一般に, 同期オペレーションを呼び出すスレッドは そのスレッドのフレームの情報を td によって指される領域に置き, td を同期オペレーションに渡す. SET_THREAD_DESC(td)を呼び出さなければならない. 同期オペレーションは同期条件をチェックし, ブロックすると 決めたときには, リンクによって指される領域をその手続きの フレームの情報と呼び出しの鎖の一つ前のフレームのデスクリプタへのリンク で満たすSET_LINK_DESC(link, td)を呼び出す.



Mitsubishi Research Institute,Inc.
Mon Feb 24 19:27:36 JST 1997