FE EXAM

マルチスレッド(1コアで複数スレッドを並行実行)

1つのコアで複数のスレッドを切り替えながら並行実行する仕組み

INTERACTIVE VISUALIZATION
スレA
スレB
スレC
切替
現在のシナリオ
1コアでの時分割実行
1つのコアの上で3つのスレッド A・B・C が短い時間ずつ交代で実行される様子を時間順に追います。
実行中のスレッド
A
シナリオ
ステップ1 / 6
STEP 1/6 — スレッド A が実行中まずスレッドAがコアを使って実行されます。このとき B と C は順番待ち(実行可能だが待たされている状態)です。1コアなので、ある瞬間に動けるスレッドは1つだけです。
解説

📌
マルチスレッドとは

1コアが時間で交代しながら処理1コアスレッドAスレッドBスレッドC

マルチスレッドとは、1つのコア(=CPU内で実際に命令を実行する装置)の上で複数のスレッド(=プログラムの中の処理の流れ)を、短い時間ずつ切り替えながら並行して進める仕組みのことです。

身近な例で考えると、1人のレジ係が3つの会計を少しずつ交互にさばくイメージです。1人(1コア)なので本当に同時に処理しているわけではありませんが、すばやく切り替えるため、お客さんからは「3つ同時に進んでいる」ように見えます。これを並行(concurrent)と呼びます。

上のツールで ▶ ボタンを押すと、1コアの上でスレッド A・B・C が順番に実行され、間にコンテキストスイッチ(切替)を挟みながら進む様子を確認できます。

📌
スレッド切替の仕組み

スレA切替退避→復元スレBコンテキストスイッチ

あるスレッドから別のスレッドへ実行を切り替える作業をコンテキストスイッチと呼びます。コンテキストとは「そのスレッドの状態」のことで、具体的には次のようなものを指します。

切替のときにOSがやること:
退避(save):今動いていたスレッドのレジスタ・プログラムカウンタ(=次に実行する命令の番地)を保存する
選択:次に実行するスレッドをスケジューラ(順番を決めるOSの機能)が選ぶ
復元(restore):次のスレッドの状態を読み込み、続きから再開できるようにする

この切替には少しだけ時間がかかり、その間はどのスレッドの仕事も進みません。これをオーバーヘッド(本来の処理以外にかかるムダな時間)と呼びます。切替が細かすぎるとオーバーヘッドが増えて遅くなるため、OSは適度な長さのタイムスライス(各スレッドへの割当時間)で区切ります。上のツールの紫色の区間が、この切替時間にあたります。

📌
マルチコアとの違い

マルチスレッド(1コア)A→B→C 交代並行(見かけ上同時)マルチコア(複数コア)ABC並列(本当に同時)

マルチスレッドとマルチコアは混同しやすいですが、「本当に同時か、見かけ上同時か」という決定的な違いがあります。

項目マルチスレッド(1コア)マルチコア
同時に動く処理数1つ(交代で実行)物理的に複数
実現方法時間で切り替える(時分割)コアを増やす(ハード)
呼び方並行(concurrent)並列(parallel)
切替オーバーヘッドあり(コンテキストスイッチ)少ない(各コアが独立)

「1コアのマルチスレッドは並行(見かけ上の同時実行)、マルチコアは並列(物理的な同時実行)」と整理しておくと混同しません。なお実際のパソコンは「複数コア × 各コアでマルチスレッド」を組み合わせており、両方の良いところを使っています。

📌
並行と並列——なぜ「同時に見える」のか

並行(1コア・時分割)ABC→ 交代で進む並列(複数コア・同時)A(コア1)B(コア2)→ 本当に同時

並行(concurrent)とは、1つのコアが複数の処理を「時間を小さく区切って交互に」こなすことです。ある瞬間に動いているのは1つだけですが、切り替えがあまりに速いため、外から見ると「同時に動いている」ように感じます。

なぜ「同時に見える」かというと、切り替えの速さが人間の感覚をはるかに超えているからです。1秒間に何千回も切り替えが起きると、人間には「全部が同時に進んでいる」としか感じられません。映画のフィルムが1秒24枚の静止画なのに動いて見えるのと同じ原理です。

一方、並列(parallel)複数のコアが文字通り同時に別々の処理を動かすことで、物理的に本当の同時実行です。
並行:1人の人間が2つの仕事を「少しずつ交互に」こなす
並列:2人の人間がそれぞれ1つの仕事を「完全に同時に」こなす

📌
競合状態と排他制御——共有データが壊れるのはなぜか

残高 = 10002スレッドが同時に書き換えると…スレA+500 を書込スレB−200 を書込どちらかの書込が消える(バグ)

マルチスレッドで気をつけなければならないのが競合状態(レースコンディション)です。これは、複数のスレッドが同じデータを同時に読み書きしようとして、結果がおかしくなる現象のことです。

なぜ起きるのかというと、「読む→変える→書く」という操作が複数ステップになっているからです。スレッドAが「残高を読んで+500した値を書こうとしている途中」でスレッドBが割り込んで書き換えると、AもBも古い値をもとに計算してしまい、片方の変更が消えてしまいます。
・スレA:残高1000を読む → 1500にして書こうとする(途中で切替)
・スレB:残高1000を読む → 800にして書く
・スレA:1500を書く → Bの「−200」がなかったことになる

これを防ぐのが排他制御(ミューテックス・ロック)です。「今Aが使っているからBは入ってこないで」とドアに鍵をかけるイメージです。鍵をかけた間は他のスレッドは外で待ち、Aが終わって鍵を開けてから次が入ります。これで1度に1スレッドだけが共有データを操作できるため、データが壊れなくなります。

関連コンテンツ