デッドロックとは

デッドロックは、複数のプロセスやスレッドが、お互いが占有しているリソースを解放するのを永久に待ち続けることで、すべての処理が停止してしまう状態のことです。

デッドロックの概要と発生条件

デッドロック(Deadlock)は、マルチタスクやマルチスレッド環境における同期処理で発生する可能性のある、深刻な問題です。これは、プログラムの実行が永遠に進まない「行き詰まり」の状態であり、システムやアプリケーションの機能不全を引き起こします。

デッドロックが発生するためには、以下の4つの条件がすべて同時に成立する必要があります。これはコフマンの4つの条件(Coffman’s four conditions)として知られています。

  1. 相互排他(Mutual Exclusion)
    • リソースが一度に一つのプロセス(またはスレッド)によってしか使用できないこと。例えば、プリンターや共有メモリ、データベースのレコードなどです。
  2. 保持と待機(Hold and Wait)
    • プロセスが、あるリソースをすでに保持しながら、別のプロセスが保持している別のリソースを待機している状態であること。
  3. 非占有(No Preemption)
    • プロセスが保持しているリソースを、そのプロセスが自ら解放するまで、他のプロセスが強制的に奪うことができないこと。
  4. 循環待機(Circular Wait)
    • 複数のプロセスが、リソースの解放を巡って環状に待機している状態であること。例えば、プロセスAがリソース1を保持し、リソース2を待機しており、プロセスBがリソース2を保持し、リソース1を待機している状況です。

これら4つの条件のうち、いずれか一つでも満たされなければ、デッドロックは発生しません。

デッドロックの具体的な例

デッドロックの典型的な例を、2つのプロセスと2つのリソースを使って説明します。

  • リソース: リソースAとリソースB
  • プロセス: プロセス1とプロセス2
ステッププロセス1の行動プロセス2の行動状態
1リソースAを占有プロセス1がリソースAを保持
2リソースBを占有プロセス2がリソースBを保持
3リソースBを要求(待機)プロセス1はリソースBが解放されるのを待つ
4リソースAを要求(待機)プロセス2はリソースAが解放されるのを待つ
デッドロックの具体的な例

この状況では、プロセス1はリソースAを保持しながらリソースBを待機し、プロセス2はリソースBを保持しながらリソースAを待機しています。お互いが相手が保持しているリソースを待ち続けるため、処理が進まなくなり、デッドロックに陥ります。

これはデータベースにおけるトランザクション処理でも頻繁に発生します。例えば、トランザクション1がテーブルAのロックを取得した後にテーブルBのロックを要求し、その間にトランザクション2がテーブルBのロックを取得した後にテーブルAのロックを要求した場合、両者の処理が停止します。

デッドロックの対策

デッドロックの発生を防ぐためには、コフマンの4つの条件のいずれかを満たさないようにシステムを設計する必要があります。

1. デッドロックの防止(Prevention)

デッドロックを事前に防ぐためのアプローチです。

  • 相互排他を排除する
    • すべてのリソースが共有可能であればデッドロックは発生しません。しかし、多くのリソース(ファイル、プリンターなど)は本質的に相互排他が必要なため、この方法は限定的です。
  • 保持と待機を排除する
    • プロセスが必要なリソースをすべて一度に要求し、すべて確保できなければ一つも保持しないようにします。
    • または、プロセスが新しいリソースを要求する前に、保持しているすべてのリソースを解放するようにします。
  • 非占有を排除する
    • プロセスがリソースを要求して待機する場合、保持しているリソースを強制的に解放させるようにします。しかし、これもすべてのリソースで可能なわけではありません(例: データベースのロック)。
  • 循環待機を排除する
    • リソースに順序を付け、プロセスは必ず決められた順序でリソースを要求するようにルールを定めます。例えば、「リソース1、リソース2の順に要求する」と決めておけば、循環待機は発生しなくなります。この方法は実装が比較的容易で効果的です。

2. デッドロックの回避(Avoidance)

システムの安全性に関する情報を事前に把握し、デッドロックに陥る可能性のあるリソース割り当てを回避するアプローチです。銀行家アルゴリズム(Banker’s Algorithm)などが有名ですが、リソースの要求量を事前に知る必要があるなど、現実のシステムでの実装は困難な場合があります。

3. デッドロックの検出と回復(Detection and Recovery)

デッドロックの発生を許容し、発生した後にそれを検出し、回復するアプローチです。

  • 検出: 待機グラフなどを利用して、システムがデッドロック状態にあるかを定期的にチェックします。
  • 回復:
    • デッドロックに関与しているプロセスを強制的に終了させます。
    • デッドロックの原因となっているリソースを、デッドロックが解消されるまで段階的に解放させます。
    • これらの回復処理は、システムに一時的な不整合をもたらす可能性があるため、慎重な設計が必要です。

多くのオペレーティングシステムやデータベース管理システムでは、これらの対策を組み合わせてデッドロックを管理しています。特にデータベースでは、トランザクションのタイムアウトを設定し、デッドロックを検出した場合にはいずれかのトランザクションを強制的にロールバックさせることで、デッドロック状態を解消するのが一般的です。

関連用語

リソースリーク | 今更聞けないIT用語集
リソース枯渇 | 今更聞けないIT用語集
ソフトウェアエンジニアリング

お問い合わせ

システム開発・アプリ開発に関するご相談がございましたら、APPSWINGBYまでお気軽にご連絡ください。

APPSWINGBYの

ソリューション

APPSWINGBYのセキュリティサービスについて、詳しくは以下のメニューからお進みください。

システム開発

既存事業のDXによる新規開発、既存業務システムの引継ぎ・機能追加、表計算ソフトによる管理からの卒業等々、様々なWebシステムの開発を行っています。

iOS/Androidアプリ開発

既存事業のDXによるアプリの新規開発から既存アプリの改修・機能追加まで様々なアプリ開発における様々な課題・問題を解決しています。


リファクタリング

他のベンダーが開発したウェブサービスやアプリの不具合改修やソースコードの最適化、また、クラウド移行によってランニングコストが大幅にあがってしまったシステムのリアーキテクチャなどの行っています。