モジュール間のデッドロックの防止方法
状況によっては、
スレッド逐次化モジュールまたは逐次化されたプロシージャー以外の機能を使用して
モジュールの同期化を制御する必要があります。例えば、
図 1 で示される状況を考慮します。
この状況では、2 つのスレッドがそれぞれ異なるスレッド逐次化モジュールでプロシージャーを実行しています (プロシージャー PROC1 はモジュール MOD1、プロシージャー
PROC3 はモジュール MOD2)。また、MOD1 はプロシージャー PROC2 を持ち、MOD2 は
プロシージャー PROC4 も持っています。再帰的呼び出しが実際に行われなくても、PROC1 は PROC4 を呼び出す場合
、MOD2 がアンロックするのを待ち、PROC3 は PROC2 を呼び出す場合、MOD1 がアンロックするのを待ちます。
モジュールはそれぞれ他方のモジュール内でスレッドによってロックされるため、これらの
プロシージャーは呼び出しを完了することができません。このタイプの問題は、モジュールへの呼び出しを逐次化した場合でも
発生する可能性があるもので、デッドロックと呼ばれます。
図 1. THREAD(*SERIALIZE) モジュールのデッドロック例

この例は、同じスレッド逐次化モジュール内の複数のプロシージャーに同時に アクセスしようとする場合に、どのようにデッドロックが発生するかを示します。
上の例のような問題を避け、スレッド・セーフのアプリケーションを確実に作成するためには、『スレッド関連の API の使用』で説明する技法を使用して、モジュールの同期化を制御できます。各スレッドについて、PROC1 または PROC3 の呼び出し元はいずれも、次
のことを行う必要があります。
- 現行スレッド以外のすべてのスレッドについてモジュールへのアクセスを、必ず同 じ順序で (例えば、MOD1 の次に MOD2) 制御する
- 現行スレッドで、必要なプロシージャーを呼び出す (PROC1 または PROC3)
- ステップ 1 の逆順で、すべてのスレッドについてモジュール へのアクセスを解放する (MOD2 の次に MOD1)
1 つのスレッドで MOD1 へのアクセス制限が正しく実行されます。MOD1 および MOD2 の すべてのユーザーは、この順序での MOD1 および MOD2 へのアクセスを制限する プロトコルを使用するため、最初のスレッドがモジュールへのアクセスを制限されてい るかぎり、他のスレッドは MOD1 または MOD2 内でプロシージャーを呼び出すことはで きません。このような状況では、同じモジュール内の複数のプロシージャーに同時にア クセスすることはできますが、このモジュールは現行スレッドでしか使用できないため、ス レッド・セーフです。
この方法は、共用記憶域へのアクセスを同期する場合にも適用できます。