デッドロックとは?意味・発生条件・防ぎ方を初心者向けに解説

デッドロックとは?意味・発生条件・防ぎ方を初心者向けに解説

AIの初心者

「デッドロック」って、プログラムが止まることだと聞いたのですが、どういう意味ですか?

AI専門家

デッドロックは、複数の処理が互いに必要な資源を持ったまま、相手の資源が空くのを待ち続けてしまう状態だよ。たとえば処理Aが資源1を持って資源2を待ち、処理Bが資源2を持って資源1を待つと、どちらも先に進めなくなるんだ。

AIの初心者

お互いが待っているだけなら、どちらかが譲れば解決しそうに見えますね。

AI専門家

人間なら譲れますが、プログラムはあらかじめ決めた手順で動きます。だから、資源を取る順番や待ち時間、異常時の戻し方を設計しておくことが大切なんだ。

デッドロックとは。

複数の処理が、相手の持つ資源を待ち続けて動けなくなる「行き詰まり状態」のことです。データベース、OS、並行処理、分散システムなど、共有資源を扱う仕組みでは重要な基礎用語です。

デッドロックとは何か

デッドロックとは何かを示す概念図

デッドロックとは、複数の処理が互いに必要な資源を保持したまま、相手が資源を解放するのを待ち続け、どの処理も先へ進めなくなる状態です。日本語では「行き詰まり」と表現されます。

ここでいう処理とは、プログラムそのものだけでなく、プロセス、スレッド、ジョブ、トランザクションなどを含みます。資源とは、データベースの行や表、ファイル、メモリ、プリンター、ネットワーク接続のように、同時利用に制限があるものです。資源を一時的に独占する仕組みは「ロック」と呼ばれます。

たとえば、処理Aが資源Aをロックしたまま資源Bを待ち、処理Bが資源Bをロックしたまま資源Aを待つと、両方が相手の解放を待つだけになります。この状態では時間が経っても自然に解決しないことが多く、システムの一部または全体が停止したように見えることがあります。

なお、検索では「デットロック」と書かれることもありますが、IT用語としては英語の deadlock に対応する「デッドロック」が一般的な表記です。

デッドロックが起きる4つの条件

デッドロックの4条件を示す説明図

デッドロック状態は、偶然処理が遅くなっただけではありません。古典的には、次の4つの条件が同時に成り立つと発生し得ると整理されます。逆にいえば、設計上どれか1つでも崩せれば、デッドロックを防ぐ方向に近づけます。

条件 意味
相互排除 ある資源を同時に1つの処理しか使えない 1台のプリンター、排他ロックされたデータ
保持と待ち 資源を持ったまま、別の資源が空くのを待つ 表Aをロックしたまま表Bのロックを待つ
循環待ち 処理同士の待ち関係が輪のようにつながる AはBを待ち、BはAを待つ
先取り不能 他の処理が保持中の資源を強制的に奪えない 書き込み途中のロックを安全に奪えない

初心者が特に押さえたいのは、デッドロックでは「処理が悪い」のではなく、資源の取り方と待ち方の組み合わせが問題になる点です。ロックはデータの整合性を守るために必要ですが、取得順序や解除条件を考えないと、整合性を守る仕組みが停止の原因になります。

データベースや共有機器で見るデッドロックの例

データベースと共有機器で起きるデッドロックの例

もっとも理解しやすい例は、データベースのロックです。処理1が表Aを更新するためにロックし、続けて表Bを更新しようとしているとします。一方、処理2は表Bを先にロックし、続けて表Aを更新しようとします。このとき、処理1は表Bを待ち、処理2は表Aを待つため、どちらも進めません。

プリンターとスキャナーのような共有機器でも同じ構図になります。処理1がプリンターを確保してスキャナーを待ち、処理2がスキャナーを確保してプリンターを待つと、両方が相手の資源を必要としたまま停止します。対象がデータでも機器でも、問題の本質は複数の資源を異なる順番で取り合うことです。

場面 処理1 処理2 起きること
データベース 表Aをロックし、表Bを待つ 表Bをロックし、表Aを待つ 互いのロック解放を待つ
共有機器 プリンターを確保し、スキャナーを待つ スキャナーを確保し、プリンターを待つ どちらの処理も進まない

単なる処理待ちであれば、相手の処理が終われば再開できます。しかしデッドロックでは、待たれている側も別の資源を待って止まっているため、待ち関係がほどけません。この違いを理解すると、通常の遅延、リソース不足、無限ループとの区別がしやすくなります。

デッドロックを防ぐ主な方法

デッドロックを防ぐ資源取得順序の説明図

デッドロック対策では、発生してから慌てて直すよりも、設計段階で起きにくくすることが重要です。代表的な方法は、資源を取得する順番を全処理で統一することです。たとえば、複数の処理が必ず資源A、資源B、資源Cの順に取得するなら、循環待ちが起きにくくなります。

もう1つの方法は、待ち時間に上限を設けることです。一定時間待っても資源を取得できない場合、いったん保持している資源を解放し、処理をやり直します。この方法は永久待ちを避ける助けになりますが、再試行が増えると処理時間が長くなるため、短すぎるタイムアウトは逆効果になることがあります。

また、必要な資源を最初にまとめて取得できるか確認し、そろわなければ何も保持しないという設計もあります。これは「保持と待ち」を崩す考え方です。ただし、資源を長く押さえすぎると他の処理を妨げるため、処理時間や競合頻度とのバランスが必要です。

対策 狙い 注意点
資源取得順序の統一 循環待ちを起こしにくくする 全処理でルールを守る必要がある
タイムアウト 永久待ちを避ける 再試行が増えると遅くなる
事前確保 保持と待ちを避ける 資源を長く占有しすぎない工夫が必要

デッドロックを検知する考え方

デッドロック検知と回復の流れを示す図

すべてのデッドロックを事前に防ぐ設計が難しい場合、システムが発生を検知して対応する方法を取ります。代表的なのは、処理と資源の関係をグラフとして見て、待ち関係に閉路がないか調べる考え方です。

たとえば、処理Aが処理Bの持つ資源を待ち、処理Bが処理Cの持つ資源を待ち、処理Cが処理Aの持つ資源を待っているなら、待ち関係が輪になります。この閉路はデッドロックの重要な手がかりです。

実際のシステムでは、待ち時間の長さ、ロックの種類、処理の状態、優先順位などもあわせて確認します。なぜなら、短時間の待ちは通常の処理でも起きるため、閉路や待ち時間だけで単純に判断すると誤検知になる可能性があるからです。検知は、監視コストと正確さのバランスを取る必要があります。

デッドロックから回復する方法

デッドロックが起きた場合は、待ち関係をどこかで断ち切る必要があります。よく使われる方法は、関係する処理の一部を停止し、その処理が保持していた資源を解放することです。どの処理を止めるかは、処理の重要度、やり直しのしやすさ、保持している資源量などを見て判断します。

データベースでは、処理を途中の安全な状態まで戻す「ロールバック」も重要です。更新途中のデータをそのまま残すと整合性が壊れるため、トランザクション開始前またはチェックポイントの状態に戻してから再実行します。

回復方法 内容 向いている場面
処理の強制停止 一部の処理を止めて資源を解放する 再実行できる処理がある場合
資源の強制解放 保持中の資源を取り上げる データ破損の危険が低い場合
ロールバック 安全な過去の状態へ戻す データベースやトランザクション処理

回復策はシステムを再び動かすために有効ですが、処理のやり直しや利用者への影響が発生します。そのため、重要なシステムでは予防、検知、回復を組み合わせて設計します。

学習時に混同しやすいポイント

デッドロックは「処理が遅い」状態とは違います。通常の待ち状態なら、待たれている処理が終われば再開できます。デッドロックでは、待たれている側も別の処理を待っているため、待ち関係が閉じた輪になっています。

また、無限ループとも異なります。無限ループは1つの処理が同じ動作を繰り返してCPUを使い続けることがありますが、デッドロックでは処理が資源待ちで止まっていることが中心です。リソース不足とも似ていますが、デッドロックは単に資源が足りないだけでなく、保持と待ちの関係が絡み合っている点が特徴です。

試験や実務で問われる場合は、まず「複数の処理」「複数の資源」「互いに待つ」「資源を保持したまま」という言葉に注目すると、デッドロック状態を見つけやすくなります。

まとめ

デッドロックとは、複数の処理が互いに必要な資源を持ったまま待ち続け、どの処理も先へ進めなくなる状態です。発生には、相互排除、保持と待ち、循環待ち、先取り不能という4条件が関係します。

防止には、資源取得順序の統一、タイムアウト、事前確保などが有効です。完全に防ぐのが難しいシステムでは、待ち関係のグラフや処理状態の監視で検知し、強制停止やロールバックで回復します。デッドロックは並行処理やデータベースの基礎なので、定義だけでなく「なぜ待ち関係がほどけないのか」まで理解しておくと、実務でも学習でも役立ちます。

更新履歴

日付 内容
2025年1月31日 初回公開
2026年5月27日 発生条件、検知、回復策の関係が追いやすい構成に調整