スマートフォンを使ってる時、動画を見ながらメールを送信したことってあるよね。ゲームをプレイしてる時も、キャラクターが動いたり敵が襲ってきたり、音が出たり、全部が一度に起こってる。普通に考えると「同時になんて無理なんじゃ?」って思うけど、実はコンピューターがめっちゃ賢い工夫をしてるんだ。その工夫のカギが「マルチスレッド」という仕組みなんだ。この記事を読めば、スマホやゲームがどうやって複数の処理を同時にこなしてるのか、その秘密がわかるよ。
- マルチスレッドは、1つのプログラムが複数の処理を同時に進める仕組みで、スマホやゲームが色々なことを一度にできるのはこれがあるから
- 実はCPUが超高速に切り替えて実行してるだけなのに、人間の目には同時に見えてる
- 敵の動き、プレイヤー操作、音声、画面描画みたいに、複数のタスク(仕事)を別々のスレッドで分担すると効率が良くなる
もうちょっと詳しく
昔のコンピューターは、1つの処理を終わらせてから次の処理を始める仕組みだったんだ。つまり、敵が動くのを全部計算し終わってから、ようやくプレイヤーの操作を処理するみたいな感じ。だからゲームはカクカクだったり、レスポンスが遅かったりした。でも今は、複数の処理を分けて(スレッド化して)、CPU側でうまく配分して実行することで、全体としてはスムーズに複数のことが進むようになったんだ。これがマルチスレッドの力。つまり、仕事を分割することで、全体の効率を上げるやり方ってわけ。
昔のやり方「順番に1個ずつ」
今のやり方「複数を同時に(見た目)」
差は、仕事の分割方法!
⚠️ よくある勘違い
→ 実際には、コアの数や容量には限界があるから、無限には増やせない。スレッドを増やしすぎるとかえって遅くなることもある。
→ 処理を分割して、待ってる間に別の処理を進めることで、全体としての効率を上げる仕組み。だからバランスが大事。
[toc]
マルチスレッドって実生活でも起きてるんだ
カフェの店員を想像してみて
マルチスレッドを理解するために、身近な例をあげるね。カフェに行った時、店員さんが何をしてるか見たことある?1人の店員さんが、あるお客さんのコーヒーを作ってるかと思ったら、別のお客さんの注文を聞いたり、別の客がいるテーブルに飲み物を運んだりしてる。でもコーヒーを作るのは機械がやってくれるから、その間に他のことができる。これって実は、マルチスレッドと同じ仕組みなんだ。店員さんがスレッド1、コーヒー機械がスレッド2みたいな感じで、複数の処理が同時に進んでるイメージ。昨日のコンビニやレストランで、店員さんがどうやって複数のタスク(仕事)を同時にこなしてたのか、思い出してみるとわかるよ。みんなが「効率的だな」って感じるのは、実はマルチスレッド的な工夫があるからなんだ。
スマートフォンで起きてること
君のスマートフォンでも、マルチスレッドが活躍してる。例えば、YouTubeで動画を見ながらLINEが来て、LINEの返信をしてる間も動画が再生されてるよね。これ、もしシングルスレッド(1つの糸だけ)だったら、動画の再生を止めて、完全にLINEの返信に切り替わるはず。でも実際は同時進行してる。それはなぜか?スマートフォンのOSが、複数のアプリケーション(アプリ)を別々のスレッドに割り当てて、CPU時間を配分してくれてるからなんだ。YouTubeアプリが使ってるスレッド、LINEアプリが使ってるスレッド、バッテリーの管理をしてるスレッド、ネット接続をしてるスレッド…こんな風に、いろんなスレッドが同時に活動して、全体として「複数のことが同時に動いてる」というユーザー体験が成り立ってるってわけ。だからスマートフォンって、すごく器用に色々なことができるんだ。
なぜマルチスレッドが必要なのか
処理の待ち時間を有効活用したい
ここが大事なポイント。プログラムが何かの処理をしてる時、ずっと何かしてるわけじゃなくて、「待つ」という時間が発生するんだ。例えば、ネットからデータをダウンロードしてる時、コンピューターは「データが届くまで待つ」という状態になってる。この時間、何もしないのはもったいないよね。そこで、別のスレッドが他の仕事をやってしまえば、全体としては時間を無駄にしないわけ。あるスレッドが「待つ」状態になってる間に、別のスレッドが「働く」状態で動いてる。これがマルチスレッドの最大の利点。つまり、待ち時間を「見張り」のようなスレッドが受け持たせて、メインの処理はどんどん進めるみたいなやり方。ゲームで言うと、敵のAIが「敵の位置を計算してる間」に、プレイヤーの操作を処理するとか、そういう使い分けをしてるんだ。
レスポンスを速くしたい
スマートフォンやWebサイトを使ってて、「反応が遅い」ってストレスに感じたことあるよね。これって、シングルスレッド(1本の糸だけ)で動いてるアプリケーションだと起こりやすいんだ。例えば、重い計算をしてる最中に、ボタンをタップしても反応がない。なぜなら、CPU全部が計算に使われちゃってて、「ユーザーのタップを受け付ける」という処理ができないから。でもマルチスレッドを使うと、スレッド1が重い計算をしてる最中に、スレッド2が「ユーザーの操作を聞く係」として待ってる。だからタップされたら、すぐに反応できるんだ。この「すぐに反応する感じ」をレスポンスが良いって言う。君たちが今のスマートフォンに「快適だな」って感じるのは、このレスポンスの良さがあるからなんだ。
プログラマーがマルチスレッドをどう使ってるか
Webサーバーの例
インターネット上のWebサーバーって、世界中から同時にアクセスされるよね。例えば、YouTubeに1000万人が同時にアクセスしてたら、全員のリクエスト(要求)に答えなきゃいけない。もしシングルスレッドだったら、1人目のリクエストを完全に処理し終わってから、2人目のリクエストを処理する…みたいに、超遅くなるはず。だから実際のWebサーバーは、1つのリクエストに対して1つのスレッドを割り当てるやり方をしてるんだ。Aさんのリクエストをスレッド1が処理してる間に、Bさんのリクエストをスレッド2が処理する。こうやって、複数のクライアント(ユーザー)のリクエストを同時にこなせるようにしてる。このやり方のおかげで、YouTubeや検索エンジンは、何万人もの人の要求に応えられるんだ。
ゲーム開発での使い方
ゲームは、さっき言ったみたいに色々なスレッドが活躍してる。例えば、RPG(ロールプレイングゲーム)を考えてみて。スレッド1は「敵のAI(人工知能)を実行する」担当。敵がプレイヤーをどう攻撃するかを計算してる。スレッド2は「プレイヤーの操作を受け付ける」担当。ボタンが押されたら、キャラを動かす命令を出す。スレッド3は「画面に画像を描く」担当。敵とプレイヤーの位置情報をもらって、画面に映す。スレッド4は「音を再生する」担当。効果音やBGMを出す。この4つが同時に動いてるから、ゲームがスムーズに進むんだ。もし順番に1個ずつやってたら、「敵の計算が終わるまで待つ」→「画面に描くまで待つ」→「音を出すまで待つ」みたいに、フレームレート(1秒間に何回画面が更新されるか)が下がって、ガクガクなゲームになっちゃう。
マルチスレッドの注意点と課題
データの競合ってなに?
マルチスレッドは便利だけど、危険もあるんだ。複数のスレッドが同じデータを同時に使おうとしたら、どうなると思う?例えば、銀行口座の残高が1000円だとしよう。スレッド1が「500円を引き出す」という処理をしてて、その途中でスレッド2が「300円を引き出す」という処理が来た。もし競合(つまり、順序がめちゃめちゃになること)が起きたら、残高が正しく計算されなくなる可能性がある。本当は200円になるはずなのに、100円になっちゃったり、1000円のままだったり。この問題のことを、プログラマーはデータの競合とかスレッドセーフでないって言う。だから、複数のスレッドが同じデータを使う時は、きちんと「誰かがそのデータを使ってる間は、他のスレッドは待つ」みたいなルール(ロックという仕組み)を入れて、順番を守らせるんだ。
バグを見つけるのが難しい
マルチスレッドのバグって、すごく見つけづらいんだ。なぜなら、スレッドの実行順序が毎回ランダムだから、「昨日は動いたのに今日は動かない」みたいなことが起きる。プログラマーが「このバグ、なんで起きたんだろう…」って悩む大きな理由の1つがマルチスレッドなんだ。だから、マルチスレッドを使う時は、プログラマーがすごく注意深く、丁寧にコードを書く必要があるんだ。テストも大変。何度も何度も実行して、「本当に全パターンで正しく動いてるか」を確認しなきゃいけない。
