🧵

プロセスとスレッド

2024/04/06に公開

概要

わかったようなわからないようなふわっとした感覚なので、改めてまとめました。

対象読者

プロセスとスレッドについてわかったようでわかってない。

プロセス

プロセスとは

実行される処理の単位。
Linuxでは、カーネルによって複数のプロセスが管理される。
一つのCPUで同時に実行できるプロセスは一つのみなので、マルチコア、CPUを用いて並列処理を実現できる。

プロセスのメモリ空間構成

このメモリ空間は、仮想メモリを指す。
仮想メモリは、MMU(Memory Management Unit)を通して、物理メモリと紐づけられている。
各プロセスには独立しており、独立したメモリ空間が割り当てられている。

  • テキストセグメント
    プログラムのソース。ReadOnlyな領域。
  • データセグメント
    文字通り変数や定数を格納するための領域。
    ヒープ領域もここ。gcがお掃除してくれるところ。
  • スタックセグメント
    関数実行中のローカル変数や、引数を管理するところ。
    スタックトレースはスタックセグメントの情報から出力されている。

プロセスの親子関係

プロセスには親子関係があり、親プロセスをフォークして子プロセスが複製される。
子プロセスは親プロセスの状態や、データにアクセスできる。
親プロセスが終了すると、子プロセスはPID1のinitプロセスの子となる。
親プロセスは、子プロセスの終了を適切に処理してプロセステーブルから削除する必要があり、それが何らかの理由でうまく行われないとゾンビプロセスが生まれる。
プロセスには、規定の物理メモリ領域が割り当てられているので、ゾンビプロセスが大量に発生するとリソースの枯渇につながる。

スレッド

スレッドとは

スレッドとは、プロセスの内部に作成される処理の単位。
スレッドは、プロセスのメモリ空間を共有する。
プロセスよりも軽量で、コンテキストスイッチにかかる時間も少ない。

マルチスレッドとシングルスレッド

  • シングルスレッド
    1プロセスで1つのスレッドを実行する。
    1つのタスクを順に実行する。
    重たいタスクがあると、その完了待ちで非効率になってしまうがシンプル。
  • マルチスレッド
    複数のスレッドを並列に実行する。
    効率よく処理を進めることができる。
    互いのスレッドの終了を待ち合うデッドロックや、メモリ空間を共有していることによるバグのリスクを抱えているため、
    スレッドセーフな実装を求められる。

両者の違い

そもそも比較するものではない気がするが、、、

プロセス スレッド
メモリ空間 独立性がある 共有する
スイッチングコスト 高い 低い

プロセスは他のプロセスから独立したメモリ空間を持ち干渉し合わないため安全だが、スイッチングにはマッピングの切り替えやディスクI/Oが発生するためコストがかかる。
一方スレッドはプロセス内で共有するため、スイッチングコストは低いがスレッドセーフな実装が必要。
ただし、スレッドもスイッチングコストがないわけではないので、スレッド数については度々議論されるのを見かける。
https://github.com/rails/rails/issues/50450

まとめ

調べれば調べるだけ新しい情報が出てくるので、一旦プロセスとスレッドの立ち位置がわかる程度にとどめました。
ただ、自分の実装がどう動くかは今後もっと深く理解しておきたいところなので次はもう一歩深いところまで調べてみたいです。

Discussion