FE EXAM

OSのスレッド(軽量な実行単位)

プロセス内に複数の「実行の流れ」を作るスレッドの仕組みと、その落とし穴(レースコンディション)を可視化します。

THREAD SIMULATOR
共有領域
スタック
実行中
現在のシナリオ
スレッドの基本構造
1つのプロセスの中に複数のスレッドができていく過程を追います。メモリは共有、スタックは独自。
スレッド数
1
シナリオ
ステップ1 / 5
STEP 1/5 — プロセスに1つのスレッドプロセスが起動した直後は「メインスレッド」が1つだけ。CPUで実行されるのはこの1スレッド。
解説

📌
スレッドとは — プロセス内の軽量な実行単位

1つのプロセス共有メモリ(コード・データ・ヒープ)スレッド1独自スタックスレッド2独自スタックスレッド3独自スタック

スレッド(Thread)は、1つのプロセスの中で並列に動く「実行の流れ」のことです。プロセスの「メモリ空間(コード・データ・ヒープ)」を全スレッドで共有しながら、各スレッドは自分のスタックだけ独自に持ちます。

身近な例えだと、「1つの台所で複数の料理人が働く」イメージです。料理人(スレッド)は同じ冷蔵庫や調味料棚(共有メモリ)を使えますが、自分の作業スペース(独自スタック)は別々に持っています。これにより材料を取り合うこともなく効率的に並列作業できる ──ただし、同じ砂糖入れに同時に手を伸ばすと事故(後述のレースコンディション)が起きます。

上のツール「スレッドの基本構造」を ▶ 自動再生すると、1プロセス内にスレッドが増えていく様子を確認できます。

📌
プロセスとスレッドの違い

項目プロセススレッド
メモリ空間独立共有(スタックのみ独自)
生成コスト重い軽い
コンテキストスイッチ重い軽い
通信プロセス間通信(IPC)が必要共有メモリで直接
独立性高(1つ落ちても他は無事)低(1つ落ちるとプロセスごと落ちる)

プロセスとスレッドは「並列処理の実行単位」という点で似ていますが、性質が大きく違います。独立性とパフォーマンスのトレードオフと覚えると整理しやすいです。


独立性が欲しいとき:プロセス(プロセス間で影響しない)
性能・通信効率が欲しいとき:スレッド(共有メモリで高速)

例えばWebブラウザは、タブごとを別プロセスにすることで「1つのタブが固まっても他は無事」を実現しています。一方、ブラウザのGUI描画はマルチスレッドで動かして、操作を滑らかに保っています。

📌
メモリ共有の利点 — 軽量で高速

共有メモリdata, queue, cacheT1T2T3

スレッドの大きな利点は「メモリ共有で簡単に協調作業できる」点です。プロセスでは別プロセスとのデータ交換に専用の仕組み(パイプ・ソケット・共有メモリAPI)が必要ですが、スレッド同士ならただの変数でやり取りできます。

メモリ共有のメリット:
生成が高速:メモリ空間をコピーする必要がない
通信が高速:変数の読み書きだけで情報交換できる
メモリ効率が良い:複数スレッドで同じデータを共有

この特性により、Webサーバー(リクエストごとに1スレッド)、ゲームエンジン(描画・物理・AIを並列化)、数値計算(同じ配列を複数スレッドで処理)など、性能が要求される場面で広く使われます。

📌
レースコンディション — 共有メモリの落とし穴

x = 0 を 2 スレッドで +1 すると…T1: x を読む(0)T2: x を読む(0)両方とも 0 を取得両方 1 を書込x = 1本来は 2 のはず!

メモリ共有は便利ですが、2つのスレッドが同じ変数を同時に更新すると、結果が壊れることがあります。これをレースコンディション(race condition)と呼びます。

典型的な発生パターン:
・スレッドA が変数 x の値(例: 0)をレジスタに読む
・OSがスレッドB に切替。B も x を読む(まだ 0)
・B が x = 0 + 1 = 1 を計算して書き戻す
・A が再開し、レジスタの古い値で x = 0 + 1 = 1 を書き戻す
本来は 2 回 +1 されて x = 2 のはずが、1 にしかなっていない

対策には排他制御(ロックやセマフォを使って同時アクセスを禁止する)が必要です。レースコンディションはタイミング次第で発生するため、テストで再現しにくい厄介なバグの代表格です。上のツール「レースコンディションの発生」シナリオで一連の流れを確認できます。

📌
スレッドのコンテキストスイッチが軽い理由

プロセス切替レジスタ退避メモリ管理切替+ ページテーブルスレッド切替レジスタ退避これだけ!

プロセス切替では仮想メモリ管理情報(ページテーブル)まで入れ替える必要がありますが、同一プロセス内のスレッド切替ではメモリ管理情報は同じままでよいため、レジスタとスタックポインタの退避・復元だけで済みます。

数字感としては、プロセスのコンテキストスイッチが数マイクロ秒かかるのに対し、スレッドのコンテキストスイッチは数百ナノ秒程度。10倍前後の差があります。

そのため、頻繁に切替が必要な並列処理(Webサーバーの1リクエスト=1スレッド方式など)ではスレッドが採用されます。「スレッドは軽量、プロセスは重い」と覚えておくとよいでしょう。

📌
実用例 — 身の回りのマルチスレッド

Webサーバー1req=1threadGUIアプリUI/処理分離並列計算CPU並列化

マルチスレッドは身近なソフトウェアで広く使われています。


Webサーバー:1リクエストごとに1スレッドを割り当てて、複数のクライアントに同時応答(Apache のスレッドモデル)
GUI アプリ:画面描画スレッドと裏で動く処理スレッドを分離し、操作中もアプリが固まらないようにする
科学計算 / 機械学習:行列演算を複数スレッドに分散して、CPU の全コアを使い切る
ゲームエンジン:描画・物理シミュレーション・AI・サウンドをスレッド分離

どれも「並列にやることで速くなる」ケースですが、レースコンディションを避けるためのロック設計が腕の見せ所になります。

📌
なぜスレッドが必要か — シングルスレッドの限界

シングルスレッド処理A入出力待ち…処理B は待ちぼうけ画面が固まる!マルチスレッドT1: 処理A入出力待ちT2: 処理B は動ける!画面はスムーズ

シングルスレッド(=実行の流れが1本だけ)のプログラムでは、1つの処理が終わるまで次の処理が始められません。ファイルの読み込みやネットワーク通信のような待ち時間の長い処理が発生すると、その間アプリ全体が止まってしまいます。

なぜスレッドが必要か。ダウンロード中でも画面操作ができる、音楽を聴きながら別の作業ができる——これらはすべて複数の処理を同時に進めたい要求から来ています。マルチスレッドにすることで、1つのスレッドが待っている間に別のスレッドが動き続けられるため、「アプリが固まる」問題を解消できます。

身近な例では、料理のながら作業が近いイメージです。お湯を沸かしながら(待機中のスレッド)、その間に野菜を切る(別のスレッド)ことで、全体の調理時間を短くできます。シングルスレッドだと「お湯が沸くまで包丁を持てない」状態になってしまいます。スレッドはこの「ながら作業」を実現するための仕組みです。

練習問題

🎯
基本情報技術者 練習問題

Q1.スレッドの説明として正しいものはどれか。
A.スレッドは独自のメモリ空間を持ち、他スレッドから完全に隔離される
B.スレッドはプロセス内の実行単位で、コード・データ・ヒープを共有する
C.スレッドはプロセスより重い実行単位
D.スレッドは1つしか作れない
Q2.マルチスレッドの危険性として最も適切なものはどれか。
A.スレッド数を増やすほどメモリ使用量が大きくなる
B.プロセスとスレッドが混在するとOSが認識できない
C.共有データへの同時アクセスで結果が予測不能になる(レースコンディション)
D.スレッド同士は通信できない
Q3.スレッドのコンテキストスイッチがプロセスのものより軽い理由として正しいものはどれか。
A.スレッドはCPUを使わないから
B.スレッドはレジスタを使わないから
C.同一プロセス内のスレッド切替ではメモリ管理情報の入替が不要だから
D.スレッドの方が優先度が高いから

関連コンテンツ