LoginSignup
26
8

More than 5 years have passed since last update.

goroutineとスレッドの違いって?

Last updated at Posted at 2018-12-10

この記事は、Go3 Advent Calendar 2018 の11日目の記事です。

はじめに

Goにはgoroutineという並行処理を簡単に実行できる機能があります。
goroutineは「goroutineとは軽量スレッドである」と説明されていますが、結局goroutineとスレッドって何が違うのかということを調べてみました。

まず最初に言うとgoroutineの実体はスレッドです。
ですが大きく3つの違いがあります。順番に見ていきましょう。

メモリ消費量

スレッドのデフォルトスタックサイズは Windows だと 1 MB、Linux だと 2 MB で
goroutineは数キロバイトで済みます。
必要に応じてヒープ領域を割り当てたり開放したりします。一方でスレッドはスレッド間のメモリが干渉し合わないように「スタックガードページ」と呼ばれる 1Mbの領域の確保から始めます。
数キロバイトで済む goroutine に比べると、10 KB だとしても100〜200倍の違いがあります。

生成と破棄に要する時間

スレッドは生成と破棄のたびに OS に要求を投げて、それが完了して返ってくるのを待つため時間がかかります。
一方で goroutine では、生成と破棄に関する操作を非常に低コストで行うことができます。

スイッチングに要する時間

スレッドがブロックされると、別のスレッドがスケジューリングされます。 プリエンプティブ方式でスレッドがスケジューリングされ、スレッドの実行がスイッチされる際にスケジューラーは全てのレジスタ、つまり 16種類の汎用レジスタ、PC(プログラムカウンタ)、SP(スタックポインタ)、16種類の XMM レジスタ、 FP co-processor の状態、16種類の AVX レジスタ、そしてモデル固有のレジスタを別の場所に保存したり、保存したそれらをレジスタに戻す処理が必要になります。これはスレッド間で迅速にスイッチングしたい場合に、無視できません。
goroutine は協調してスケジューリングされ、スイッチングが発生したときも、たった 3つのレジスタ(PC、SP、DX)しか保存したり、レジスタに戻したりしません

まとめ

Goは並行処理をするにあたってgoroutineを使うことによってメモリ消費量を抑えてました。
メモリ使用量が多くなり過ぎると、スワップが発生し性能低下を招くため、小さなメモリ使用量で済むというのは大きな利点だと思います。
ここで述べた以外にもgoroutineはスレッドよりも起動時間が早かったり、メモリ消費量がすくないためスレッドに比べてもより多く
の並行処理を実行することができるとも言われています。(他にも利点は色々とある)
並行処理が簡単に実行できて、スレッドよりも数多くの並行処理を実行できるgoroutineという機能があるGoは最高ですね。
(気付いた点等ございましたら、お知らせください)

26
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
8