複数のモジュールを介したデータの共用方法

THREAD(*SERIALIZE) 制御仕様書キーワードを使用してモジュールへのアクセスを逐次化 すると、各モジュール内でグローバル・データへの順次アクセスは必ず行われますが、 モジュールを介した共用データへの順次アクセスは必ずしも行われません。共用データ に一度に 1 つのスレッドだけがアクセスできるようにするのは、プログラマーの役目で す。

次の場合には、同じデータに 2 つ以上のモジュールがアクセスできます。

例えば、モジュール A 内のプロシージャー A が、モジュール B 内のプロシージャー B にポインターを引き渡すと、プロシージャー B はそのポインターを静的変数内に保管 します。このような場合、両方のモジュールは、モジュール A 内で実行するスレッド が基本記憶域にアクセスしているときにその記憶域にアクセスできます。プロシージャ ー B が戻ると、別のスレッドがモジュール B 内のプロシージャーを呼び出し、基本記 憶域にアクセスできるようになります。モジュール A およびモジュール B 内で静的記憶域 へのアクセスが逐次化されると、各モジュール内の同じ記憶域に同時にアクセスできなくなりま す。以下に、同じデータにアクセスできる 2 つのモジュールの例を示します。

図 74. マルチスレッド環境でのデータの共用例
 *-------------------------------------------------------------------------
 * .---------------.
 * |               |
 * | ある記憶域    |<---------------- 共有記憶域へのポインター
 * |               |                  (モジュール A の MyPtr の呼び出し)
 * '---------------'                  (モジュール B に静的変数として保管)
 * モジュール A
 * モジュール A のグローバル変数
D MyPtr          S            *
D SomeStorage    S          10A    based(MyPtr)
C          eval   SomeStorage = 'Init value'
C          callp  ProcB(MyPtr)                2 
C          eval   SomeStorage = *BLANKS       3 
 *-------------------------------------------------------------------------
 * モジュール B
 * モジュール B のグローバル変数
D SavedPtr       S            *
D SomeStorage    S          10A    based(SavedPtr)
 * モジュール B の ProcB
P ProcB          B                 export
D ProcB          PI
D   PtrParm                   *
C                 eval     SavedPtr = PtrParm          6 
C                 return                               7 
P                E
 * モジュール B の ProcB2
P ProcB2         B                 export
D ProcB2         PI
D   PtrParm                   *
C                 if       SomeStorage = 'Init value'  8 
C                 ....
C                 return
P                E

ProcA が ProcB を呼び出す (行  2 ) と、モジュール A およびモジュ ール B は 1 つのスレッドが使用しているため、他のスレッドは MyPtr が 指示する記憶域にアクセスできません。ProcB はポインターをモジュール B の静的記憶 域に保管 (行  6 ) して、戻ります (行  7 )。これで 、モジュール B には活動状態のスレッドがなくなったので、別のスレッドがモジュール B を自由に呼び出せる状態です。別のスレッドが ProcB2 を呼び出した場合、最初のス レッドによる行  3  の処理と、2 番目のスレッドによる 行  8  の処理が前後したり、同時に行われる可能性があります。これ らのイベントの順序は定義されていません。SomeStorage = 'Init value' をテストする のに使用されるコードは、成功する場合もあれば、失敗する場合もあります。

共用データへのアクセスを同期するには、プログラム内でロジックを使用するか、C ま たはプラットフォーム関数によって提供される同期化手法を使用します。詳細については、以下 の URL で、プログラミングのトピックからマルチスレッド・アプリケーションの資料を 参照してください。

http://www.ibm.com/eserver/iseries/infocenter