プロセス/スレッド/デーモンを簡単に区別してみる
はじめに
「プロセス」「スレッド」「デーモン」。
どれも開発を行う際には日常的に使う言葉ですが、口頭で説明を求められると少し悩む方もいるかと思います。
- プロセス=実行中のプログラム?
- スレッド=プロセスに似た何か?
- デーモン=バックグラウンドで動いているプログラム?
のような感覚値を持っていて実務上ではなんとかなることもありますが、どこかで困る時が出てくると思います。
例えば、後輩に聞かれた時など上記の感覚値で説明もできますが、もう少しだけ掘り下げると双方勉強になると思います。
今回はプロセス、スレッド、デーモンを一次情報(POSIX や man-pages)を読んできちんと説明できるような記事にしていきます。
この記事ではLinuxを前提に一次情報をなるべく参照しながら、「プロセス/スレッド/デーモン」を簡単に区別してみようと思います。
プロセス
プロセスは「プログラムの実行単位」などと認識されていることも多いですが、一次情報ではもう少し構造的に扱われています。
POSIXの定義を確認すると、プロセスは既存のプロセスからfork()やposix_spawn() のような関数で生成される存在として説明されています(いわゆる親子プロセスの関係です)。
Linuxのfork(2)のmanも同じく、呼び出し元プロセスを複製して新しいプロセスを作る、というニュアンスで説明しています。
簡単に記述をまとめると、下記のようになります。
- 親プロセスと子プロセスは、それぞれ独立したアドレス空間を持つ(子のプロセスでヒープを書き換えても、親プロセスには見えない)
- CPU時間などのカウンタは子プロセス側では0から始まる
スレッド
スレッドは「プロセスから作られる、共有メモリを持つ実行単位」というイメージを持っている方は少なくないと思います。
POSIXでは「プロセス内の制御の流れ」として説明されています。
POSIXのスレッド周辺(Threads章や pthread_create()の仕様)では、
- スレッドは必ずどこかのプロセスの中に属する
- 同じプロセス内のスレッドは
- アドレス空間
- ファイルディスクリプタ
- 多くのプロセス状態
を共有する
- 各スレッドは
- 自分専用のスタック
- 実行位置(プログラムカウンタ)
- スレッド ID、スケジューリングに関わる属性
を持つとあります。
Linux の pthread_create(3) の man でも、「呼び出し元プロセス内に新しいスレッドを開始する」と説明されています。
そして malloc() などで確保したヒープ領域は、同じプロセス内のスレッドからはすべて見えるという記述があります。
デーモン
デーモンは「裏で動いているプロセス」というイメージを持つ方が多いと思います。
Linuxのdaemon(3)/daemon(7) を読むと下記のような旨が書いてあります。
- プロセスであり、そのプロセスを制御端末から切り離す
- 親プロセスから独立してバックグラウンドで動き続ける
まとめ
以上をまとめると、下記になります。
| 項目 | 内容 |
|---|---|
| プロセス | 独立したアドレス空間を持つプログラムの実行単位 |
| スレッド | プロセスから作られる、同一プロセス内で共有メモリを持つ実行単位 |
| デーモン | 親プロセスから切り離されて独立して動くプロセス |
参考
POSIX 全体(The Open Group Base Specifications Issue 7, IEEE Std 1003.1)
Base Definitions(用語の定義)
関連する関数の仕様(fork, posix_spawn, pthread_create など)
fork(2)
pthread_create(3)
daemon(3)
daemon(7)
Discussion