【低レイヤ入門】ドリフの散髪屋コントで見切るマルチタスクと仮想メモリの正体 | UNIX Cafe

* 当サイトでは、コンテンツの一部に広告を掲載しています。

System Note $ cat /proc/ai-disclosure

本記事の構成および論理分析にはAI(人工知能)を使用しています。情報の正確性は、システム管理者(UNIXユーザー)による手動検証済みです。

【低レイヤ入門】ドリフの散髪屋コントで見切るマルチタスクと仮想メモリの正体 | UNIX Cafe

OSやCPUの資料を読んでいると、最初に引っかかる不思議な部分があります。

タスク1も、タスク2も、タスク3も、みんな平然と同じようなアドレスを使って動いていることです。たとえば、どのプログラムも「自分のプログラムの先頭は 0x00000 です」という顔をしています。

でも、実際の物理メモリ(RAM)の上で全員が本当に同じ場所にいたら大事故です。

  • タスク1の変数をタスク2が上書きして踏み潰す
  • タスク3のスタックに別のプログラムの戻り先データが混ざる
  • プログラムの状態が壊れ、異常終了や暴走につながる

では、現代のOSはどうやってそれを避けているのでしょうか。

答えは、意外なほど原始的です。CPUに「今はこの人の番です」と思わせるために、OSが裏で状態を保存し、別の状態を復元し、アドレス変換の表まで超高速で差し替えています。

要するに、マルチタスクと仮想メモリは、超高速で行われる「舞台転換」なのです。

今回はその一見複雑な仕組みを、あの「ドリフの散髪屋コント」のような目まぐるしい舞台セットの入れ替えに例えて、視覚的に見ていきましょう。

目次

今回のゴール:3つの役割をバラバラに解きほぐす

マルチタスク、仮想メモリ、ページフォルト。この3つの言葉を同時に混ぜて見ようとするから、OSの仕組みはかなり複雑で難解に見えてしまうのです。

この記事のゴールは、これらを一度バラバラに分解し、次のように明確に分けて理解することです。

  • マルチタスク = CPUの「作業状態」を保存・復元する仕組み
  • 仮想メモリ = 同じ「論理アドレス」を別々の「物理メモリ」へ対応させる仕組み
  • ページフォルト = 必要なページがまだ準備できていないことをOSへ知らせる「例外(通知)」

この3つの役割をそのまま教科書通りに読んでも頭が痛くなりますが、あの「ドリフの散髪屋コントの舞台」に置き換えると、驚くほど見通しがよくなります。

それでは、さっそく舞台裏の配役から覗いてみましょう。

登場人物の配役(低レイヤとコントの対応表)

まずは、この散髪屋コントの配役を決めます。ここがブレると舞台が混乱するので、しっかり整理しておきましょう。

💈 加トちゃん = CPU

目の前の命令をひたすら順番に実行する、基本的にはとても真面目な職人です。

ただし、CPU自身は「この作業はタスク1のものか、タスク2のものか」を深く考えているわけではありません。現在のレジスタ、プログラムカウンタ、そして「いま見えているアドレス空間」だけを信じて動きます。

散髪屋でいえば、目の前の「1番席」に座っている客の髪を、何も疑わずにハサミで切る職人です。

🪑 1番席 = 論理アドレス(仮想アドレス)

プログラム(タスク)側から見える住所です。

タスク1にとっての 0x00000 も、タスク2にとっての 0x00000 も、見かけ上は全く同じ「1番席」です。

CPUはこの1番席(論理アドレス)を目がけて命令やデータを取りに行きます。ただし、その席が実際の物理メモリのどこに繋がっているかは、裏の仕掛けによって変わります。

🎬 舞台監督 = OSのスケジューラ

「誰を次に動かすか」をコントロールする係です。

「そろそろタスク1を止めて、次はタスク2を動かそう」と裏で判断を下します。CPUが気分で勝手に客を変えるわけではなく、タイマー割り込みやシステムコールをきっかけに、舞台監督(OS)が主導権を握って演者を交代させます。

👥 お客さん(志村・ブー・仲本)= タスク(プロセス)

それぞれが独立して動く、別々のプログラムです。

それぞれのタスクは、自分専用のレジスタ状態、スタック、プログラムカウンタ、メモリ空間を持っています。

物理メモリの上では全員がバラバラの場所にいるのに、本人たちはみんな「自分はあの1番席に座っている」と思い込んでいる。ここが仮想メモリの面白いところです。

🔄 回転床 = ページテーブル

ページテーブルは、論理アドレスを物理アドレスへ変換するための表です。

正確には、CPUやMMUは「今使うページテーブルの場所」を示すレジスタを参照します。そのレジスタが別のページテーブルを指すように切り替わると、同じ論理アドレスでも、実際にアクセスする物理メモリが変わります。

散髪屋コントでいえば、職人からは同じ1番席が見えているのに、床がグルッと回って、別の客がいつの間にか特等席に現れる仕掛けです。

マルチタスク:すべては「客の状態」を保存するところから始まる

まず、加トちゃん(CPU)がタスク1(志村)を実行しているとします。

加トちゃんは1番席に座っている志村の髪を、一所懸命に切っています。「霧吹きをシュッと吹きかけ、右手にハサミを持ち、次は左のモミあげを切るぞ」と頭の中で覚えています。

低レイヤの世界でいえば、CPUが以下の「状態(コンテキスト)」をすべて保持して動いているフェーズです。

  • 汎用レジスタ: いま右手に持っている道具(計算データやポインタ)
  • プログラムカウンタ: 次はどこを切るかの記憶(次に実行する命令のアドレス)
  • スタックポインタ: 散髪タオルの位置や一時的な道具置き場(関数のローカル変数や戻り先)
  • フラグレジスタ: 「さっきのカット、ちょっと切りすぎたかな?」という状態(演算結果のステータス)

「盆回り」のBGMとともに、舞台監督が乱入する

ここで、OSのタイマー割り込みが非情にも鳴り響きます。

舞台監督(OS)は、まず「いまの客(志村)の状態」をすべてノートに書き写して保存します。

  • ハサミは右手に持っていた
  • 次は左のモミあげの予定だった
  • タオルは首に2重に巻いていた

これを全部メモしておかないと、あとで志村が戻ってきたときに、続きから安全に再開することができません。

CPUの世界でいえば、これがレジスタ、プログラムカウンタ、スタックポインタなどの退避です。現在のタスク1の全レジスタ情報を、メモリ上の特定の領域へと超高速で退避させます。

この保存された状態を使えば、タスク1は、何事もなかったかのように「左のモミあげ」から散髪を再開できるのです。

別の客の状態を復元する

次にOSは、タスク2を動かすことにします。

客(志村)の状態をメモにしまい終えたら、舞台監督(OS)は次に動かすタスク2(高木ブー)のメモを取り出します。

  • この客の髪は、前回ここまで切っていた
  • ハサミはこの位置、タオルは頭に巻いていた
  • 次に実行する命令(プログラムカウンタ)はここ
  • 道具置き場(スタック)はここ

舞台監督(OS)は、このメモの通りに加トちゃん(CPU)の右手や頭の中身、つまりレジスタやプログラムカウンタをタスク2の状態へと一気に入れ替えます。

この瞬間、加トちゃん(CPU)にセットされている状態は、志村用の状態からブー用の状態へと一気に切り替わります。

CPUは舞台裏を知らない

ここで面白いのは、加トちゃん(CPU)本人は、舞台裏でどんなドタバタ劇(割り込み処理)が起きたのかを一切知らないということです。

「あれ?さっきまで目の前にいたの志村じゃなかったっけ…?」などと考えたりはしません。ただ目の前に差し出されたレジスタとプログラムカウンタをそのまま信じて、愚直に次の命令を実行するだけです。

これが、低レイヤにおける文脈切り替え、すなわち「コンテキストスイッチ」の正体です。

マルチタスクの基本は、決して物理的なCPUの数を増やすことではありません。1つのCPUに複数のタスクを細切れに担当させ、その交代のたびに「作業状態(コンテキスト)の保存と復元」を猛烈なスピードで繰り返すことなのです。

仮想メモリ:同じ「1番席」を別の場所につなぐ

ここまでで、CPUがタスクを切り替える仕組み(マルチタスク)は見えてきました。

しかし、まだ大きな謎が残っています。

タスク1(志村)もタスク2(ブー)も、なぜ衝突することなく、まったく同じ 0x00000000 という論理アドレスを使えるのでしょうか。

ここで登場するのが、もう一つの主役である「仮想メモリ」です。

加トちゃん(CPU)が「よし、0x00000000 のデータを読みに行くぞ」と言っても、それがそのまま実際の物理メモリ(RAM)の 0x00000000 番地を指すわけではありません。

CPUと物理メモリの間にMMU(メモリ管理ユニット)という装置が入り、「ページテーブル」というアドレス変換表を使って、実際の居場所に翻訳しているのです。

たとえば単純化すると、舞台裏では次のような対応表(マッピング)が作られています。

  • タスク1(志村)の 0x00000000 ➔ 物理メモリの 0x00010000 番地へ
  • タスク2(ブー)の 0x00000000 ➔ 物理メモリの 0x00020000 番地へ
  • タスク3(仲本)の 0x00000000 ➔ 物理メモリの 0x00030000 番地へ

回転床が「前提」をひっくり返す

加トちゃん(CPU)から見れば、どのタスクを相手にしているときも、自分は同じ「1番席」に向かってハサミを動かしているように見えます。

しかし、舞台裏では「回転床」がグルリと回っています。職人からは同じ位置に見えていても、床が回ることで、別の客が同じ特等席へと運ばれてきているのです。

論理アドレス(1番席)という見かけの住所は同じでも、参照するページテーブル(回転床の角度)が違えば、実際に触っている物理メモリ(客の実体)は完全に別物です。

OSがタスクを切り替えるとき、レジスタやプログラムカウンタだけでなく、このアドレス変換の前提も切り替えます。

つまり、マルチタスクは「作業状態のすり替え」で、仮想メモリは「同じ住所が別の実体を指す仕組み」です。

この2つの仕掛けがガッチリと噛み合うことで、加トちゃん(CPU)は同じ席でずっと作業しているつもりのまま、複数のプログラムを互いに干渉させることなく、安全に動かせるのです。

ページフォルト:「おい舞台監督!客がまだ席に座ってねえぞ!」

ここまでの仕掛けで、マルチタスクと仮想メモリの連携はバッチリです。しかし、最後にもう一つのトラブルシューティングの仕組みが必要になります。

もし、加トちゃん(CPU)がある論理アドレス(1番席の指定の場所)を読もうとしたとき、そのデータ(ページ)がまだ実際の物理メモリ上に存在しなかったらどうなるでしょうか。

散髪屋コントでいえば、加トちゃんが「よし、次は頭の後ろを刈るぞ」とハサミを構えて振り向いたら、あるはずの1番席に客が座っていないという状態です。

「おい、誰もいねえぞ!」

この瞬間に舞台は一度ストップします。これがCPUの例外処理、「ページフォルト」の正体です。

ページフォルトは「大急ぎで準備しろ」の合図

「フォルト(Fault:欠陥/失敗)」という名前がついているため、大エラーが起きてプログラムがクラッシュしたように思えるかもしれません。しかし、これは即座に強制終了という意味ではありません。

むしろOSにとっては、「必要なページがまだ準備できていないから、大至急用意して!」という業務連絡(通知)なのです。

連絡を受けた舞台監督(OS)は、状況を素早くチェックして次のように動きます。

  • 楽屋(ストレージ)にいる場合: 「ただいま出番です!」と、実行ファイルやスワップ領域にあるデータを大急ぎで物理メモリ(席)へ読み込む。
  • 新しい席が必要な場合: 新しく確保したスタック領域などであれば、その場でまっさらな新しいページ(席)を用意する。

つまり、客がまだ楽屋にいるだけなら、舞台監督(OS)が急いで連れてきて席に座らせます。そして、加トちゃん(CPU)は、何事もなかったかのように、ストップした「全く同じ命令」をもう一度実行します

予約のない客には「金だらい」が落ちてくる

しかし、予約されていない、まったく無関係の客(不正なアドレスへのアクセス)だった場合は話が別です。

その場合、舞台監督(OS)は即座にプログラムを強制終了させます。

低レイヤの世界でいう「セグメンテーションフォールト(アクセス違反)」です。ドリフのコントなら、頭上から凄まじい音を立てて「金だらい」が落ちてきて、そのタスクは一瞬で撃沈(プロセス終了)することになります。

CPUは騙されていることに気づかない

ここまでの流れをまとめると、現代のOSがやっていることの本質は、驚くほど「舞台的」です。

加トちゃん(CPU)は、どこまでも純粋で愚直です。常に目の前にある状態だけを信じて、与えられた命令をひたすら実行し続けています。

その裏で、OSとハードウェア(MMU)は次のような連携プレーを超高速で繰り返しています。

  • OSのスケジューラが、タイマー割り込みをきっかけにCPUを止め、現在のタスクの状態を保存し、別のタスクの状態を復元する(マルチタスク)。
  • MMU(メモリ管理ユニット)が、ページテーブルという変換表を見て、プログラムが見ている住所を実際の居場所に翻訳する(仮想メモリ)。
  • OSがページテーブルを切り替えることで、同じ「1番席」という論理アドレスを指していても、アクセスする実際の物理メモリ(実体)をガラリと入れ替える。

これほど目まぐるしい舞台転換が行われていても、CPUは「別の客に替わったな」とは夢にも思いません。ただ、手元にあるレジスタと、その瞬間見えているアドレス変換を100%信じて、次の命令を実行するだけです。

だからこそ、マルチタスクとは「超高速で行われる演者のすり替え」であり、仮想メモリとは「同じ席に別の実体を対応させる舞台装置」なのです。

一見すると複雑に思えるOSとCPUの低レイヤの世界。しかしその仕組みを紐解いてみれば、あのドリフの散髪屋コントのように、緻密に計算された「完璧な舞台裏のドタバタ劇」によって支えられているのです。

結び:この「力技」が世界を動かしている

最初は、マルチタスクや仮想メモリという言葉が、何か巨大な魔法のように見えるかもしれません。

しかし、こうして分解してみると、やっていることは意外なほど具体的で人間味あふれる「力技」です。

  • いまの状態をメモして保存する
  • 次の人の状態を読み込んで復元する
  • アドレス変換の表(回転床)を切り替える
  • 足りないもの(客や道具)があれば、舞台監督が裏で面倒を見る

もちろん、実際のCPUやOSの世界には、より高速化するためのキャッシュ(TLB)や、安全のための特権モード、ページ保護など、さらに複雑な仕掛けが山ほど積み重なっています。それでも、彼らがやろうとしている根っこにある考え方は、この散髪屋コントの構造とまったく同じです。

私たちが普段何気なく打っている lscat の裏でも、ブラウザのタブの裏でも、PCやスマートフォンの中では、今この瞬間に1秒間に何万回もの目まぐるしい舞台転換が起きています。

  • 加トちゃん(CPU)は、今日も真面目に1番席の客だけを相手にしている。
  • 舞台監督(OS)は、裏で汗をかきながら客を入れ替えている。
  • MMUは、ページテーブルという回転床を見て、同じ席をまったく別々の楽屋へとつないでいる。

そして私たちは、その超高速のドタバタ劇を上から眺めながら、「アプリが同時に動いている」と呼んでいるのです。

(ドリフの名作コント、そして現代のOSとCPUのエンジニアたちに敬意を表して。)

ダメだこりゃ。すごすぎる。次いってみよう!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

のいのアバター のい UNIX Cafe マスター

Macintosh Color Classicから始まった旅は、長いWindows時代を経て、Windows10のサポート終了をきっかけにUNIXの世界へ戻ってきました。UNIX Cafeでは、UNIX・Linux・そしてMacな世界を、むずかしい言葉を使わず、物語のように書いています。プログラミングは、アイデアをコンピューターに伝えるための言葉です。簡単な単語と文法を覚えれば、誰でもコマンドを使えます。ぜひ一度、やさしいプログラミングの世界をのぞいてみてください。

目次