モニターの使用

モニターは、ミューテックスでは容易に処理できない特別なアクセス問題を解決します。たとえば、データの読み込みは多数のスレッドで同時に行い、データの書き込みは 1 つのスレッドのみで行うことができます。スレッドがデータを書き込んでいる間は、他のスレッドからの読み込みアクセスを禁止できます。

モニターは、クリティカル セクションで使用し、クリティカル セクションが保護データで実行するデータ アクセスの種類を宣言します。データアクセスの種類とは、読み込み、書き込み、または参照を指します。

モニターの同期機能を拡張し、クリティカル セクションで参照を行うこともできます。この参照機能は、実際のアプリケーションで大変役立ちます。参照用のクリティカル セクションは、データの読み込みや保護データの書き込みを行います。条件によっては、保護データ項目の書き込みを行わない場合もあります。このクリティカル セクションがアクティブの場合には、単にデータを読み込むのみのクリティカル セションは複数実行できますが、参照または書き込みを行う他のクリティカル セクションは実行できません。参照しているスレッドが保護データへの書き込みを必要と判断した場合は、参照ロックから書き込みロックへの変換を要求します。変換プロセスは、データを読み込むクリティカル セクションがすべて終了した後で実行され、データの読み込みや書き込みを行う他のクリティカル セクションがデータにアクセスするのを防ぎます。参照用のクリティカル セクションは、保護データ項目に排他的にアクセスし、書き込み処理を行います (この状態は、参照用のクリティカル セクションが保護データ項目を読み込んだときの状態を保証します)。

次のコードは、表内の項目数を数えたり、表に項目を追加したりする複数のスレッドのアクセスを制御するモニターを示します。このコードでは、次の処理を行います。

  • 項目数を数えるために複数のスレッドがデータへアクセスすることを可能にします。
  • 項目数を数えるスレッドが動作しているときには、項目をテーブルに追加するスレッドを実行しません。
  • 表に項目を追加するスレッドを 1 つのみ実行します。このスレッドの実行中は、項目数を数える他のスレッドによる表へのアクセスを禁止します。
 Working-Storage Section.
 78  table-length                   value 20.
 01  table-monitor              usage monitor-pointer.
 01  table-current              pic x(4) comp-x value 0.
 01  table-1.
     05  table-item-1           pic x(10) occurs table-length.

 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-current
     open table-monitor

* Add an item to table-1, this is a writer critical section
     set table-monitor to writing
     if table-current < table-length
         add 1 to table-current
         move 'filled in' to table-item-1(table-current)
     end-if
     set table-monitor to not writing

* Count items in table-1, this is a reader critical section
     set table-monitor to reading
     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-monitor to not reading

簡単な参照用のクリティカル セクションの例を示します。

 Working-Storage Section.
 01  data-monitor       usage monitor-pointer.
 01  data-value         pic x(4) comp-x value 0.

* Initialization code, executed while in single threaded 
* mode
     open data-monitor

* Add an item to table-1, this is a browser critical section
     set data-monitor to browsing
     if data-value < 20
         set data-monitor to writing 
             converting from browsing
         add 5 to data-value
         set data-monitor to not writing
     else
         set data-monitor to not browsing
     end-if

このような簡単な確認のために参照ロックを使用することは推奨されません。通常、参照ロックを使用する必要があるのは、実際に書き込みロックが必要かどうかを決定するために多大な作業が必要で、アプリケーション全体でマルチスレッドを最大限に利用する場合のみです。他にも、アプリケーションでマルチスレッドのレベルを最大にするためのさまざまなモニター変換があります。