モニタ (同期)

並行計算の分野における**モニタ**（）とは、共有オブジェクトの状態が複数のスレッドから同時にアクセスされることを防ぎ、かつ状態が変化するまで待機させるような、同期のための構成概念である。モニタはスレッドに、排他アクセス権を再取得してを再開する前に、特定の条件が満たされるまで待機するために、排他アクセス権を一時的にあきらめさせるメカニズムを提供する。モニタはミューテックス（ロック）と、少なくとも1つの**条件変数**（）から成る。条件変数は、オブジェクトの状態が変化したときに明示的にシグナルされ、このときミューテックスは条件変数を待機している別のスレッドに一時的に明け渡されている。

モニタの別の定義として、ミューテックスをラップするスレッドセーフなクラスまたはオブジェクトのことを指す。

が発明し、 言語に最初に実装され、Solo Operating System でのプロセス間通信方式として使われた。

共有リソース（例えば変数やハードウェア機器などの計算資源）への同時アクセスを防止するための単純な排他制御にはミューテックスを使えばよいが、通常ミューテックスを獲得できるまでスレッドは待機し続けることになる。モニタは特定の条件が満たされるまでスレッドが効率的かつ柔軟に待機できる手段を提供する。

## 相互排他
モニタは以下のものから構成される:
* 共有リソースを操作するプロシージャ群（モニタプロシージャ、モニタ関数）
* ミューテックスロック
* リソースと結び付けられた変数
* 競合状態を防ぐために仮定されるモニタ不変条件

モニタ・プロシージャは何かをする前にロックをかけ、処理が完了するか、ある条件を待つことになるまでそれをかけておく（条件については後述）。各プロシージャがロックを解放する際に不変条件が真であることを保証するなら、競合状態となるようなリソースの状態は各タスクからは見えないということになる。

単純な例として、銀行口座のトランザクションのためのモニタを考える。

 **monitor** account {
   *int* balance := 0
   
   **function** withdraw(*int* amount) {
     **if** amount **if** *test* **then** wait(cv) という文があったとき、この `wait(cv)` から戻ってくるまでに別のプロセスが動作して条件変数を再び偽にする可能性がある。そのため、この文を `'''while''' ''test'' '''do''' wait(cv)` のように書き直して処理を続行する前に再度条件変数をチェックしなければならない。

ある条件変数で待っているプロセス群全てを実行可能状態にする実装もある。例えば、複数のプロセスが何らかの記憶装置に空きができるのを待っている場合などに有効である。というのも記憶装置上の領域を解放した場合、その解放したサイズと待っているサイズがどう対応するかはスケジューラにはわからないため、とりあえず全部を実行可能とする必要があるためである。

条件変数の実装例を以下に示す:

 conditionVariable{
   int queueSize = 0;
   semaphore lock;
   semaphore waiting;
   
   wait(){
      lock.acquire();
      queueSize++;
      lock.release();
      waiting.down();
   }
   
   signal(){
      lock.acquire();
      if (queueSize > 0){
         waiting.up();
      }
      lock.release();
   }
 }

## 歴史
Per Brinch Hansen はアントニー・ホーアのアイデアに基づいて最初にモニタを考案し実装した。その後ホーアが論理的フレームワークを構築し、本来のセマフォと能力的に等価であることを示した。

以下のようなプログラミング言語でモニタがサポートされている。
* Concurrent Pascal
* C#やVB.NETなどの.NET言語（`System.Threading.Monitor`クラス）
* C++（C++11以降の標準C++ライブラリにおける`std::mutex`と`std::condition_variable`の組み合わせなど）
* Java（とを経由したサポートのほか、Java 1.5以降はとも用意されている）
* Delphi（`System.SyncObjs.TConditionVariableMutex`クラス）
* Mesa
* Python
* Ruby
* Squeak Smalltalk

その他、多数の言語およびライブラリによってサポートされている。POSIXスレッドライブラリ (Pthreads) ではミューテックスと条件変数を表現する抽象オブジェクト`pthread_mutex_t`と`pthread_cond_t`およびそれらを操作する関数群が用意されている。Boost C++ライブラリの`boost::mutex`と`boost::condition_variable`の実装には、POSIX環境ではPthreadsが利用されている。これらの設計は、前述のC++11で標準化されたスレッドライブラリの原型にもなった。なお、Windows APIには条件変数の直接的なサポートが長らく存在しなかったため、BoostのWin32実装では匿名セマフォが使われている。Microsoft Windows VistaおよびMicrosoft Windows Server 2008以降で条件変数のネイティブAPIサポートが追加された。

## 脚注
### 注釈

### 出典

## 外部リンク

*"Monitors: An Operating System Structuring Concept" by Charles Antony Richard Hoare
*"Signalling in Monitors" by John H. Howard
*"Experience with Processes and Monitors in Mesa" by Butler W. Lampson and David D. Redell
*"Block on a Condition Variable" by Dave Marshall
*"Strategies for Implementing POSIX Condition Variables on Win32" by Douglas C. Schmidt and Irfan Pyarali
*Condition Variable Routines - Apache Portable Runtime ライブラリより
*wxCondition description
*Condition Variables - 1.69.0 - Boost.Fiber
*ZThread Condition Class Reference
*Wefts::Condition Class Reference
*ACE: ACE_Condition&lt; MUTEX &gt; Class Template Reference - 
*QWaitCondition Class | Qt Core 5.12 - Qt
*
*
*threads::shared - スレッド間でデータ構造を共有するための Perl 拡張