- 複数のプロセスやスレッドが共有リソースに同時アクセスして壊れる問題を防ぐための同期制御機構のこと。整数カウンターで同時アクセス可能数を管理する
- 複数のプロセスが同じリソースに同時アクセスするとデータ競合(レースコンディション)が起きてデータが壊れる。セマフォはこのリスクを整数カウンターで制御することで防ぐ
- DBへの同時書き込み・プリンタキューの制御・コネクションプールの上限管理など、リソースに同時アクセスできる上限数を設けて安全に共有したい場面で使われる同期プリミティブだ
【深掘り】これだけ知ってればOK!
バイナリセマフォはカウンターが0か1のみの形式で実質的にミューテックスと同等の排他制御を行う。カウンティングセマフォは初期値をNに設定することで「同時N件まで許可」という制御が実現できるため、DBコネクションプールの最大接続数制限に活用されている。Pythonのthreading.Semaphore・JavaのSemaphoreクラスなど高水準APIとして提供されているため直接書く機会は減っているが、仕組みの理解は設計力に直結する。
セマフォを複数使う場合の最大の落とし穴がデッドロックだ。プロセスAがセマフォX→Yの順で取得し、プロセスBがY→Xの順で取得しようとすると循環待ちが発生して永遠に進まなくなる。全プロセスで取得順序を統一することがデッドロック防止の鉄則で、設計ドキュメントに明示的に定義しておく習慣が実務事故を防ぐ。
Webサーバーの同時接続数制限・DBコネクションプールの管理・メッセージキューの処理数制御など、アプリケーション層でも実質的にセマフォの考え方が使われている。コードで直接書かなくても、フレームワークや設定の裏に隠れているため仕組みの理解は実務で生きる。
よくある誤解
セマフォとミューテックスは同じものという誤解
ミューテックスはロックを取得したスレッドのみが解放できる「所有権あり」の排他制御だ。一方セマフォは取得と解放を異なるスレッドが行えるため、スレッド間のシグナリング(通知)にも使える。「プロデューサーがV操作、コンシューマーがP操作」という非対称な使い方はセマフォにしかできない。バイナリセマフォとミューテックスは動作が似ているが、この所有権の有無が設計上の根本的な違いになる。
セマフォを使えばデッドロックは起きないという誤解
セマフォはデッドロックを「防ぐ道具」ではなく「同期を制御する道具」だ。複数のセマフォを取得する順序を設計しないまま使うと、循環待ちによるデッドロックは容易に発生する。デッドロックが実際に発生した場合、スレッドダンプを取得して循環待ちの連鎖を特定するのが診断の基本手順になる。
会話での使われ方

この処理、スレッド数の上限をセマフォで制御しているんですが、V操作の呼び出し漏れがあってたまにハングアップするみたいです。with文に変えたら解消されました。
バックエンドエンジニアがコードレビューで発見した不具合を報告している場面。V操作忘れは実務でよく起きるセマフォのバグで、コンテキストマネージャー形式への変更が定石の修正だ。




DBコネクションプール、最大10接続で制限しているのはカウンティングセマフォで実装してます。取得順序もアーキテクチャ設計書に明記しました。デッドロック対策も済んでいます。
インフラ担当がシステム設計レビューで実装方針を説明している場面。接続数制限はカウンティングセマフォの典型ユースケースだ。




セマフォとミューテックスって何が違うんですか?バイナリセマフォはミューテックスと同じじゃないですか?
勉強会で新人エンジニアがメンターに質問している場面。「動作は似ているが所有権の有無が根本的に異なる」という違いは初学者がつまずきやすいポイントだ。
【まとめ】3つのポイント
- 「セマフォの正体」:整数カウンターでリソースの空き数を管理し、P操作で取得・V操作で返却することで複数プロセス間の安全なリソース共有を実現する1965年生まれの同期プリミティブだ
- デッドロックは使い方次第で起きる:セマフォを複数使う場合は取得順序を全プロセスで統一することがデッドロック防止の鉄則で、設計段階での明文化とwith文の活用が事故を防ぐ
- 今日のコードではAPIの裏に隠れている:DBコネクションプール設定・スレッドプール上限など、アプリケーションの設定値の背後にセマフォの考え方が使われており、仕組みを理解することで性能チューニングの精度が上がる
よくある質問
- QセマフォのP操作・V操作の名前の由来は何ですか?
- A
PはオランダのProberen(試みる)、VはVerhogen(増やす)に由来します。提唱者のダイクストラがオランダ人であるため、オランダ語の頭文字が使われました。現代のAPIではwait/acquire(P相当)、signal/release(V相当)という名前が一般的です。
- QPythonでセマフォを安全に使うベストプラクティスは何ですか?
- A
threading.Semaphore(n)をwith文で使うのが最も安全です。with semaphore: という形式にすることで、例外が発生してもV操作(解放)が自動的に呼ばれるため、解放忘れによるデッドロックを防止できます。非同期処理にはasyncio.Semaphoreが対応しています。
- Qデッドロックが発生したときの診断方法は何ですか?
- A
Javaではjstackコマンドでスレッドダンプを取得し、BLOCKED状態のスレッドの待機関係を確認します。Pythonではfaulthandlerモジュールが使えます。循環待ちの連鎖を見つけることがデッドロック診断の核心です。根本対処はリソース取得順序の統一です。
- Qセマフォとミューテックスの違いは何ですか?
- A
最大の違いは所有権の有無です。ミューテックスはロックを取得したスレッドのみが解放できます。セマフォは取得と解放を異なるスレッドが行えるため、スレッド間の通知・シグナリングにも使えます。カウンティングセマフォは複数件の同時アクセスを許可できる点もミューテックスにはない特性です。
この用語と一緒に知っておきたい用語
| 用語 | この記事との関連 |
|---|---|
| リソース | リソースとの関係を知ると全体像がつかみやすくなります。コンピューターを動かすための性能や、プロジェクトを進めるための人員・時間といった資源のこと! |
| Python | Pythonとの関係を知ると全体像がつかみやすくなります。シンプルで読みやすい文法を持つ汎用プログラミング言語。AIライブラリ(TensorFlow・PyTorch)・データ分析(pandas・NumPy)・Web開発(Django・FastAPI)まで幅広く使える |
| アイコン | アイコンを押さえると本記事の理解がさらに深まります。アプリやファイル、操作ボタンなどをひと目でわかる小さな絵で表したもの、それがアイコンだ |
| 排他制御 | 排他制御は関連分野でよく登場する重要キーワードです。複数のプロセスやスレッドが同じデータや資源に同時にアクセスすることを防ぎ、一度に1つの処理だけがアクセスできるよう制限する制御の仕組みのこと |
| ダンプ | ダンプは関連分野でよく登場する重要キーワードです。システムがクラッシュやフリーズした瞬間のメモリの内容をそのままファイルに書き出したもののこと。英語の「dump(ぶちまける)」が語源で、DBのデータを書き出す操作もダンプと呼ぶ |
【出典】参考URL
https://docs.python.org/ja/3/library/threading.html#semaphore-objects :Python公式 threading.Semaphore
https://e-words.jp/w/セマフォ.html :セマフォの定義(e-Words)
https://www.ipa.go.jp/ :IPA 情報処理推進機構


コメント