ミューテックスの使用

データ共有の最も単純な問題は、処理中のある時点で複数のスレッドが同時に互いに排他的に共有データへアクセスする場合です。この共有データにアクセスするコードの部分はクリティカル セクションと呼ばれます。これらのクリティカル セクションは、共有データ項目に論理的に関連付けられたミューテックスを使用することで保護できます。「ミューテックス (mutex)」は、mutual exclusion (相互排他) から派生した用語です。データ項目に関連付けられたミューテックスは、クリティカル セクションが実行される前にロックされ、終了された後にロック解放されます。

保護するデータにアクセスする前に、すべてのスレッドがミューテックスをロックすることが非常に重要です。スレッドが 1 つでもこの同期方式に失敗し、ミューテックスをロックできなかった場合は、予期しない結果が発生します。

たとえば次のコードは、項目を追加するため、または項目数を調べるために表にアクセスする、2 つのクリティカル セクションを保護する方法を示しています。作業場所節のデータ項目 table-xxx は、table-mutex によって保護されます。

この例では、あるスレッドが表を読み込んでいる間に別のスレッドがその表にデータを追加するのを防ぐために、ミューテックスが必要となります。

 Working-Storage Section.
 78  table-length        value 20.
 01  table-mutex         usage mutex-pointer.
 01  table-current       pic x(4) comp-x value 0.
 01  table-max           pic x(4) comp-x value 0.
 01  table-1.
    05  table-item-1     pic x(10) occurs 20.

 Local-Storage Section.
 01  table-count         pic x(4) comp-x.
 01  table-i             pic x(4) comp-x.

* Initialization code executed while in single-threaded mode
     move 0 to table-max
     open table-mutex

* Add an item to table-1, this is a critical section
     set table-mutex to on
     if table-current < table-length
         add 1 to table-current
         move 'filled in' to table-item-1(table-current)
     end-if
     set table-mutex to off

* Count items in table-1, this is a critical section
     set table-mutex to on
     move 0 to table-count
     perform varying table-i from 1 by 1 
             until table-i > table-current
         if  table-item-1(table-i) = 'filled in'
             add 1 to table-count
         end-if
     end-perform
     set table-mutex to off

ミューテックスを使用する上での 1 つの問題は、アプリケーション内でのマルチスレッドのレベルが厳密に制限されることです。たとえば、表に項目を追加するプログラム、または表内の項目数を数えるプログラムなど、いくつかのプログラムからなるアプリケーションがあるとします。このアプリケーションでマルチスレッド処理を最大にするために、複数のスレッドを使用して表内の項目数を同時に数えたいとします。ただし、あるプログラムが表に項目を追加している場合には、別のプログラムで項目の追加や項目数の計算を行いたくありません。

この問題を解決するには同期プリミティブを使用します。同期プリミティブは、読み取り専用のクリティカル セクションでは複数のスレッドをアクティブにし、書き込み可能なクリティカル セクションではあるスレッドがアクティブのときは他のスレッドのアクセスを許可しません。このような同期プリミティブの例としては、モニターがあります。