モジュール間のデッドロックの防止方法

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

この例は、同じスレッド逐次化モジュール内の複数のプロシージャーに同時に アクセスしようとする場合に、どのようにデッドロックが発生するかを示します。

上の例のような問題を避け、スレッド・セーフのアプリケーションを確実に作成するためには、『スレッド関連の API の使用』で説明する技法を使用して、モジュールの同期化を制御できます。各スレッドについて、PROC1 または PROC3 の呼び出し元はいずれも、次 のことを行う必要があります。
  1. 現行スレッド以外のすべてのスレッドについてモジュールへのアクセスを、必ず同 じ順序で (例えば、MOD1 の次に MOD2) 制御する
  2. 現行スレッドで、必要なプロシージャーを呼び出す (PROC1 または PROC3)
  3. ステップ 1 の逆順で、すべてのスレッドについてモジュール へのアクセスを解放する (MOD2 の次に MOD1)

1 つのスレッドで MOD1 へのアクセス制限が正しく実行されます。MOD1 および MOD2 の すべてのユーザーは、この順序での MOD1 および MOD2 へのアクセスを制限する プロトコルを使用するため、最初のスレッドがモジュールへのアクセスを制限されてい るかぎり、他のスレッドは MOD1 または MOD2 内でプロシージャーを呼び出すことはで きません。このような状況では、同じモジュール内の複数のプロシージャーに同時にア クセスすることはできますが、このモジュールは現行スレッドでしか使用できないため、ス レッド・セーフです。

この方法は、共用記憶域へのアクセスを同期する場合にも適用できます。