##
4 Semaphore オブジェクト

セマフォ (semaphore) は、計算機科学史上最も古い同期プリミティブの一つで、 草創期のオランダ計算機科学者 Edsger W. Dijkstra によって発明されました (彼は`acquire()`と`release()`の代わりに `P()`と`V()`を使いました)。

セマフォは`acquire()` でデクリメントされ`release()`で インクリメントされるような内部カウンタを管理します。 カウンタは決してゼロより小さくはなりません; `acquire()` は、 カウンタがゼロになっている場合、他のスレッドが`release()` を呼び出すまでブロックします。

クラス `Semaphore`( | [value])

  オプションの引数には、内部カウンタの初期値を指定します。 デフォルトは`1`です。

`acquire`( | [blocking])

  セマフォを獲得します。

  引数なしで呼び出した場合: `acqure()` 処理に入ったときに 内部カウンタがゼロより大きければ、カウンタを 1 デクリメントして 即座に処理を戻します。`acqure()` 処理に入ったときに 内部カウンタがゼロの場合、他のスレッドが `release()` を呼び出してカウンタをゼロより大きくするまでブロックします。 この処理は、適切なインターロック (interlock) を介して行い、 複数の `acquire()` 呼び出しがブロックされた場合、 `release()` が正確に一つだけを起こせるようにします。 この実装はランダムに一つ選択するだけでもよいので、ブロックされた スレッドがどの起こされる順番に依存してはなりません。 この場合、戻り値はありません。

  blocking 引数の値を真にした場合、引数なしで呼び出した場合と 同じ処理を行って真を返します。

  blocking 引数の値を偽にした場合、ブロックしません。 引数なしで呼び出した場合にブロックするような状況であった場合には 直ちに偽を返します。それ以外の場合には、 引数なしで呼び出したときと同じ処理を行い真を返します。

`release`( | )

  内部カウンタを 1 インクリメントして、セマフォを解放します。 `release()` 処理に入ったときにカウンタがゼロであり、 カウンタの値がゼロより大きくなるのを待っている別のスレッドが あった場合、そのスレッドを起こします。