はじめに
プロセスについて学んだことをメモします。
訂正、追記ビシバシお待ちしております。
プロセスとは
プロセスとは、プログラムが動いている状態のことを表します。プログラムが動いている実行状態を表す全ての情報を含めてプロセスと呼びます。
例えば、ターミナルで下記のコマンドを実行したとすると、
ls コマンド入力 → [Enter] → lsコマンド実行
以上を「lsのプロセスが生成される」と表現します。
皆さんが普段ターミナルから打ち込んで使っているコマンドはもちろん、シェルであるbashなどもプロセスとして動いてます。
何となく、プロセスのイメージが掴めたでしょうか?
ただ、プロセスをもっと噛み砕いて説明すると下記のように言い換えることができます。
CPUが、プログラムに記載された順番と命令文にしたがって、あるメモリのデータに対して演算を行なっている状態。
実行中のプログラムが利用するデータは、全てメモリに書き出してから使用することになります。演算の結果生じた値、コマンドラインで入力された値、通信して受け取ったデータなどなど..それらのデータはメモリに入れてから使用されるため、CPUはプログラムの実行中にメモリだけを見ていればいいことになります。
プロセスが動作しているとき、上記したような様々な値が複雑に変化しており、それらは一つ一つのプロセスごとに固有のものです。それぞれのプロセスが持つ固有の様々な値をコンテキストと呼びます。Linuxカーネルではプロセス一つ一つに対して、task_stract構造体というデータ構造を準備しており、プロセスがもつコンテキスト情報を全てtask_stract構造体で管理しています。Linuxカーネルがプロセスを操作する際は、task_stract構造体に対して操作を行います。
task_struct構造体
task_struct構造体は、取り扱うデータの種類によって、内部で2つのセグメントに別れています。
テキストセグメント
プログラムの命令列(実行されるプログラムそのもの)
データセグメント
スタックポインタ(スタック領域のどこを見ているのか)や、プログラムカウンタ(プログラムのどこを実行しているか)などの、プロセス管理用のデータ領域の情報や、実際に用いている変数の値などが格納されています。
プロセスの生成
Linuxでは、親プロセスから子プロセスがコピー(fork)されて生成されます。これは要するに、自分のコピーを子供として生成するということです。
子プロセスが生成されると、その子プロセスには、子プロセス用のメモリ領域が割り当てられます。割り当てられたメモリに、親プロセスのデータセグメントをコピーすることで、プロセスとして動き出します。実行するプログラム自体は親プロセスと共有し、実際に用いる変数の値などは自身の子プロセス専用のものにアクセスすることになります。
プロセスの親子関係の例をあげるなら、bashの上でlsコマンドが動作する時は、親プロセスであるbashの、子プロセスとしてlsが生成されているということになります。
単純に親プロセスをコピーしただけでは全く同じ動作をするプロセスが新しく誕生するだけなので、子プロセスとしてbashのコピーを生成した後に、その子プロセスのtask_struct構造体のデータを書き換えることで、lsとして動作させています。
引用
【Linuxの「プロセス」って何だろう? -“応用力”をつけるためのLinux再入門(13)】
http://www.atmarkit.co.jp/ait/articles/1706/23/news010.html
【イケてるエンジニアになろうシリーズ 〜メモリとプロセスとスレッド編〜 -もろずblog】
http://moro-archive.hatenablog.com/entry/2014/09/11/013520#4