初級では「作業部屋(プロセス)と作業員(スレッド)」と捉えました。中級では、独立の安全さと共有の速さのトレードオフ、そして共有ゆえの危うさを見ます。
中級の解説は準備中のため、中級の内容を表示しています。
概要 — まず全体をつかむ
詳細 — 1段階ずつ追う
これは何をする係?
同じ「同時に処理を進める」でも、プロセスとスレッドではメモリの扱いが正反対です。
- プロセスは独立 — 互いにメモリが分離されています。他プロセスの領域は見えないので安全ですが、その分、切り替えや情報の受け渡しが重い。
- スレッドは共有 — 同一プロセス内では同じメモリを共有します。データの受け渡しが要らず速いが、同じ場所を同時にいじると競合が起きます。
アニメーション『プロセスとスレッド』を開く
つまり「分離=安全だが重い/共有=速いが危うい」という対の性質です。
登場人物メモ:
- ※1 コンテキストスイッチ — CPUが処理対象を素早く切り替える動作。切り替えには手間(コスト)がかかる
- ※2 排他制御 — 共有データを一度に1つだけが触れるようにする仕組み(ロックなど)
仕事の流れ
- CPUは、一度に扱える処理の本数に限りがある
- そこでコンテキストスイッチ※1 で、処理対象を高速に切り替える
- 人間から見ると、多数の処理が同時に進んでいるように見える
- 切り替えの判断(誰に、いつCPUを渡すか)はOSのスケジューラが行う
この「素早く切り替えて同時に見せる」土台は、CPU の動き方そのものです。
並行と並列、そして競合
並行(concurrent)と並列(parallel)は違います。
- 並行 — 1つのCPUが素早く切り替えて、複数の処理を代わる代わる進める(同時に見えるが、瞬間瞬間は1つ)
- 並列 — 複数のCPUコアが、本当に同じ瞬間に別々の処理を実行する
なぜ共有メモリは便利で危険なのか。 スレッドが同じメモリを共有できると、データの受け渡しが速く便利です。しかし、2つのスレッドが同じデータを同時に読み書きすると、結果が実行の巡り合わせで変わってしまう——これが競合状態(レースコンディション)です。
防ぐには排他制御(ロック)※2 を使い、共有データを一度に1つのスレッドだけが触れるようにします。ただしロックの掛け方を誤ると、互いに相手のロックを待って止まるデッドロックを招くこともあります。速さと安全は、ここでも綱引きになります。
⚠️ うまくいかないとき
- 競合状態 — 共有データの同時書き換えで、結果が不定になる
- デッドロック — 複数スレッドが互いのロックを待ち続けて止まる
- 切り替えコスト過多 — スレッドを増やしすぎ、コンテキストスイッチばかりで遅くなる
- 1プロセスの巻き添え — 共有メモリゆえ、あるスレッドの暴走が同プロセス全体を壊す
なお、プロセスごとにメモリを分離するこの隔離の考え方は、Linux のコンテナが「プロセスを箱に閉じ込めて独立させる」土台にもつながっています。独立と共有の使い分けは、OSの根っこにある設計思想です。
関連する知識
理解度チェック
そのまま解けます(成績は保存されません)。無料アカウントを作ると、学習の記録と進捗の山登りが始まります。
問1. プロセスとスレッドのメモリの扱いとして正しいのは?
問2. 複数のスレッドが同じデータを同時に書き換え、結果が実行の巡り合わせで変わってしまう問題を何という?
問3. 「並行(concurrent)」の説明として正しいのは?
問4. デッドロックが起きるのはどんなとき?
問5. プロセスどうしのメモリが分離されていることの効果として正しいのは?
問6. 排他制御(ロック)を使う目的は?
問7. CPUが処理対象を素早く切り替える動作を、カタカナで何という?
問8. 誰に・いつCPUを渡すかを判断する、OSの中の担当を何という?