##
7.5.4 Semaphore オブジェクト

これはコンピュータ科学の歴史の中で最も古い同期プリミティブの1つであり、 オランダのコンピュータ科学者 Edsger W. Dijkstra によって発明されました (彼は`acquire()`と`release()`の代わりに `P()`と`V()`を使いました)。

セマフォは`acquire()`でデクリメントされ`release()`で インクリメントされる内部カウンタを管理します。 カウンタが0より小さくなることは決してありません。 カウンタが0であることを`acquire()`メソッドが見いだしたとき、 他のスレッドが`release()`を呼び出すまでブロックされます。

class `Semaphore`( | [value])

  オプション引数は内部カウンタの初期値を与えます; デフォルトは`1`です。

`acquire`( | [blocking])

  セマフォを獲得します。

  引数なしで呼出したとき: 内部カウンタが0より大きいならば、 1だけデクリメントし直ちに戻ります。 内部カウンタが0ならば、他のスレッドが`release()`を呼出し カウンタを0より大きくするまでブロックされます。 複数の`acquire()`呼出しがブロックされる場合、 `release()`がそれらのうちのただ1つを起こすよう、 適切な内部ロックを行ないます。 その実装はランダムに1つを選び出すかもしれません。 そのためブロックされたスレッドが起こされる順序に依存してはなりません。 このケースの返り値はありません。

  blockingをTrueで呼出したとき: 引数なしで呼出した場合と同じことを 行ない、Trueを返します。

  blockingをFalseで呼出したとき: ブロックされません。 引数なし呼出しにおいてブロックされるような状況ならば、直ちにFalseを返します。 そうでないなら引数なし呼出しと同じことを行ない、Trueを返します。

`release`( | )

  セマフォを解放し、内部カウンタを1インクリメントします。 カウンタが0で、他のスレッドが0より大きくなるのを待っているのなら、 そのスレッドは起きます。