まずは簡単な用語整理
マルチタスクとは
複数のタスクを切り替えて実行できるシステムのこと
- タスクがプロセスの場合、→ マルチプロセス
- タスクがスレッドの場合、→ マルチスレッド
プロセスとスレッドのおさらい
プロセス
プロセスはプログラムの実行単位のこと。
プロセスの中身は「実行プログラム」や「変数の値」がある。
OS(Linuxカーネルなど)がこのプロセスを切り替えながら実行する。
スレッド
スレッドにはカーネルスレッドとユーザースレッドの2種がある。
カーネルスレッド
カーネルスレッドの実体はプロセス。軽量プロセスとも呼ばれる。
他スレッド(つまり他プロセス)と変数の値などを共有している。
ユーザースレッド
ユーザースレッドは、1つのプロセスの中にある擬似的なスレッド。軽量スレッドとも呼ばれる。
あくまで1つのプロセスの中で複数の擬似スレッドがあるだけ。
つまりマルチコアの恩恵を受けられない。
goroutine
goroutine
Goではgoroutineを使って、簡単に並行処理プログラミングが行える。
(詳しい説明は後で)
並行と並列の違い
並行処理と並列処理
- Concurrent(並行)は「複数の動作が、論理的に、順不同もしくは同時に起こりうる」こと
- Parallel(並列)は、「複数の動作が、物理的に、同時に起こること」
並列は並行の部分集合である。(並列⊂並行)
並列性はランタイムの性質
プログラムが並列実行されるかどうかは完全にCPUの論理コア数に依存している。
(1つの論理コアでは同時に1つのプロセスしか実行できない)
私たちはあくまで並列に走って欲しいと思う、並行性のあるコードを書いているだけである。
goroutineの説明に戻ります
goroutine is ユーザースレッド
goroutineはユーザースレッドである。
func main() {
go myFunction() // myFunctionがgoroutine化される
}
ユーザースレッドであるgoroutineの並列実行
goroutineはカーネルスレッドに紐づけられる
goはgoroutineをキューで管理し、キューから取り出してカーネルスレッドに割り当てる。
そのカーネルスレッドがCPUコアで実行される。
まとめ:goroutineによる並行処理のメリット
- カーネルスレッドの数が膨れ上がることはない(C10K問題を回避)
- goroutineはカーネルスレッドよりタスク切り替えが高速
- goroutineはカーネルスレッドよりも省メモリ