コース一覧
OS入門:プロセス・メモリ・ファイルシステム
デッドロック

OS入門:プロセス・メモリ・ファイルシステム

OSがCPU・メモリ・ストレージをどのように管理しているかを、プロセス、スレッド、仮想メモリ、ファイルシステム、同期と並行性から体系的に学びます。アプリケーションの裏側で何が起きているかを説明できるようになります。

1
OS とは
0. コンピューターとOSの役割15分
1. OSの歴史(バッチ→マルチタスク→マルチユーザー)15分
2. カーネルとユーザーランド15分
3. システムコールの仕組み15分
4. Linux / macOS / Windows のアーキ比較15分
2
プロセスとスレッド
0. プロセスとは15分
1. スレッドとプロセスの違い15分
2. コンテキストスイッチ15分
3. スケジューラとアルゴリズム15分
4. プロセス間通信(IPC)15分
3
メモリ管理
0. メモリ階層(レジスタ→キャッシュ→RAM→ディスク)15分
1. 仮想メモリ15分
2. ページングとスワップ15分
3. mmap とメモリマップトファイル15分
4. ガベージコレクション概要15分
4
ファイルシステム
0. ファイルシステムとは15分
1. i-node とディレクトリ15分
2. ext4 / APFS / NTFS の違い15分
3. ジャーナリングと耐障害性15分
4. パーミッションと所有者15分
5
同期と並行性
0. レースコンディション15分
1. Mutex と Semaphore15分
2. デッドロック15分
3. 非同期と並行15分
4. イベントループと epoll15分

OS入門:プロセス・メモリ・ファイルシステム

01コンピューターとOSの役割
02OSの歴史(バッチ→マルチタスク→マルチユーザー)
03カーネルとユーザーランド
04システムコールの仕組み
05Linux / macOS / Windows のアーキ比較
06プロセスとは
07スレッドとプロセスの違い
08コンテキストスイッチ
09スケジューラとアルゴリズム
10プロセス間通信(IPC)
11メモリ階層(レジスタ→キャッシュ→RAM→ディスク)
12仮想メモリ
13ページングとスワップ
14mmap とメモリマップトファイル
15ガベージコレクション概要
16ファイルシステムとは
17i-node とディレクトリ
18ext4 / APFS / NTFS の違い
19ジャーナリングと耐障害性
20パーミッションと所有者
21レースコンディション
22Mutex と Semaphore
23デッドロック
24非同期と並行
25イベントループと epoll

OS入門:プロセス・メモリ・ファイルシステム

デッドロック

口座ごとに鍵を分けたら、送金が止まった

鍵を口座ごとに持たせて、別々の口座なら並行に動けるようになりました。ところが送金は 2 つの口座を触ります。減らす側と増やす側の両方に鍵をかけないと、片方だけ減った途中の状態を他人に見せてしまうからです。

A から B へ送る処理は、A の鍵を取り、B の鍵を取り、それから残高を動かします。ちょうど同じ瞬間に、別のスレッドが B から A へ送っていたとします。

プレーンテキスト

スレッド 1                        スレッド 2
A の鍵を取った                    B の鍵を取った
B の鍵が空くのを待つ  ←────────  B の鍵は 2 が持ったまま
A の鍵は 1 が持ったまま  ────────→  A の鍵が空くのを待つ

1 は B が空くまで動きません。2 は A が空くまで動きません。そして、どちらも待っている間は自分の鍵を手放しません。この 2 つは永久に再開しません。デッドロック です。

CPU 使用率は 0% のまま、例外もタイムアウトも出ず、ただリクエストが返らなくなります。しばらくすると、同じ口座に来た他のリクエストも同じ鍵の前に積み上がり、スレッドプールが枯れてサーバー全体が応答を止めます。

待ちの輪ができている

矢印にすると、待ちが輪になっています。

diagram (will load when visible)

デッドロックの正体はこの輪です。裏を返せば、輪ができないようにさえすれば起きません。

取る順番を、全員でそろえる

輪ができたのは、1 が A から B の順で取り、2 が B から A の順で取ったからです。全員が同じ順序で取ると決めておけば、この形は作れなくなります。

Python

def transfer(src, dst, amount):
    first, second = sorted([src, dst], key=lambda a: a.id)
    with first.lock:
        with second.lock:
            ...

口座 ID の小さいほうから取る、と決めました。B から A への送金でも、内部では A の鍵から取りにいきます。先に A を取れた側が必ず B も取れるので、2 つが向かい合うことがありません。

順序を決めきれない場面では、待ちに上限を設けます。lock.acquire(timeout=2) で取れなければ、持っている鍵をいったん全部返し、少し待ってやり直す。RDB がデッドロックを検出して片方のトランザクションをロールバックし、アプリに再試行させるのも同じ考え方です。

条件は 4 つあるが、潰すのは 1 つでよい

教科書では、相互排除・持ったまま待つ・横取りできない・待ちが循環する、の 4 つがすべて揃ったときにデッドロックが成立すると説明されます。順序の固定は 4 つ目を、タイムアウトは 3 つ目を潰しています。どれか 1 つ崩せば足ります。

このレッスンに出てくる用語

意味があいまいなまま進んだ語は、ここから読み直せます。

  • 処理計算や代入を表す長方形
  • スレッド1 つの質問に紐づく返信の集まり
  • デッドロック複数トランザクションが互いの解放を待ち、永遠に止まる状態
  • ロック「他の人触らないでね」と DB に予約する
  • リクエストWeb 通信の基本単位、ブラウザの問い合わせとサーバーの返答
  • サーバークライアント(ブラウザなど)がリクエストを送り、サーバーがレスポンスを返す。
  • トランザクション「全部成功 or 全部なかったことに」をまとめる単位
  • ロールバック「ROLLBACK」のカナ表記
生田 陸人
監修生田 陸人
ゆめさくエンジニア / 現役ソフトウェアエンジニア監修者プロフィールを見る →
編集 ゆめさく編集部·公開 2026/05/27·更新 2026/08/26

関連レッスン

  • 非同期と並行

    並行と並列の違い、I/O 待ちの間に他の仕事を進める非同期処理の考え方を、コールバックから async/await への進化とあわせて初学者にも分かる形で解説します。

  • イベントループと epoll

    I/O 完了イベントを一スレッドで順次処理するイベントループと、その基盤となる epoll や kqueue を使って大量同時接続をさばく仕組みを解説します。

  • Mutex と Semaphore

    同時に一つしか入れない Mutex と、N 個まで入れる Semaphore の違いを、所有権の概念と具体的な使いどころを示しながら分かりやすく整理します。

  • レースコンディション

    複数スレッドが同じ資源を同時に変更し実行順で結果が変わるレースコンディションの正体と、アトミック操作やロックで防ぐ具体策を実務目線で解説します。

分からないところは Tap (AI先生) に質問できます

24 時間いつでも、あなたのレベルに合わせて日本語で答えます。