Diary

Diary

日々学んだことをアウトプットする場として初めてみました

並行処理入門

Goにおける並行処理入門

この記事では、Goにおける並行処理を実現するための準備。

次回以降、実際にコードを書いて確かめていきたい。

WHY 並行処理

ムーアの法則が破綻し限界を迎えるにつれ、単純に従来のやり方ではスピードを上げ続けることができなくなった。

その流れでマルチコアプロセッサーが登場し、これをうまく利用することが必要となった。そのための処理が並行処理である 。

並行処理と並列処理

並行処理と並列処理はごっちゃにされることが多いが、分けて考える必要がある。

並行処理

コンテキストスイッチを切り替えながら、複数の処理を「論理的に」実行すること

目的は「他を待たせないこと」

並列処理

並行処理の一部

マルチコアの利用による計算処理の高速化などが目的。(πの値の計算におけるspigotアルゴリズムなど)

また、次のような言葉もある

並行性はコードの性質を指し、並列性は動作しているプログラムの性質を指す。つまり、並列性はプログラムのランタイムの性質でありCPUのコアなどに依存する。

非同期処理

非同期処理は、並列or並行のどちらの処理を利用しても実現可能

分散処理

次のような方法が考えられる

  • スケールアップ(マシンの処理性能アップ)
  • スケールダウン(サーバーの数を増やす)

マルチプロセス

プロセス内で子プロセスを生成する

ただ、次のような問題点が生じやすい

  • プロセスの生成は、オーバーヘッドが大きい
  • プロセス間通信も、オーバーヘッドが大きい
  • 並行処理固有のバグが生じやすい

コルーチン(yield, async/await)

  • OSのファイバーを使って実現
  • メリット
    • メモリ空間が同じため、coroutine間で同じデータを共有可能
    • 切り替えのタイミングをプログラムの中で制御できる
  • デメリット
    • 並行処理はできるが並列処理は無理
    • マルチコアを生かすには、スレッドを利用する必要がある

ゴルーチン

  • メリット
    • カーネルスレッドの数が膨れ上がることがない(C10K問題を回避)
    • スレッドによりタスクの切り替えを行う
    • 複数のOSスレッド上にマッピングして同時に実行されるため、並列でも動作する

並行処理の難しさ

  • データ競合(data race)
    • 読み込み中に書き込んでしまうこと
  • 原子性
    • 特定の文脈下で分割不能
  • デッドロック
    • 全ての並行なプロセスが、お互いの処理を待ち合っている状態
  • ライブロック
    • 並行処理を行なっているけれど、その操作はプログラムの状態を全く進めていない
  • リソース枯渇