並行プロセスについてのメモ
オペレーティングシステムという本で勉強をしていて、並行プロセスについてのメモを書いていきます。
最初はメモなど取らずに勉強していってたのですが、だんだん難しくなって理解が薄すぎる状態になっていったので、noteにメモをとっていこうと考えました。
紙のノートにコードなど書いて流れをつかもうとしてたのですが、紙のノートだとメモ書きであとで読み返しにくいと思いました。
CPUの仮想化
CPUの仮想化(物理的には1つのcpuだけど、プロセス毎にcpuが存在するかのように振る舞うように作られていること)によりシステムの中には同時に複数のプロセスが実行される。
このため、複数のプロセス間でシステムの資源を競合したり、同期、強調が必要になってくる。
プロセスの相互交渉
CPUディスパッチャ
CPUの仮想化により、プロセスと同じ数の仮想CPUが作られることで同時に複数のプロセスが実行できる。
プロセスに仮想CPUを割り当てるのが、CPUディスパッチャ。
同時に複数のプロセスを実行できるのは効率的だけど、複数のプロセスが相互に干渉しあってしまうという問題も出てくる。
入出力機器を取り合ったり、同時に同じファイルに書き込もうとしたり。
同時に複数のプロセスを問題なく実行するためには、プロセス間の相互干渉を正しく制御する必要がある。
プロセスの相互交渉の問題は3種類ある
しっかり定義を頭に入れとかないと、あとあと混乱するので、下記の定義をしっかりと把握しておく。
・協調
複数のプロセスがお互いに協調し、情報交換しつつ共通の目的のために処理を進めることを協調という。
・競合
自分自身のプロセスの進行には関係ないけど、メモリのような、1個しかない同じリソースを取り合うなど、お互いに他のプロセスの存在を考慮しないといけないことを競合という。
・干渉
自分のプロセスを進めるために、他のプロセスを中断しないといけないなど、はっきりと他のプロセスの邪魔をする、影響を与える場合をことを干渉という。
プロセス競合のイメージ
競合は2つのプロセスが1つのリソースを共有して使わないといけないイメージ。
例えば、メモリを共有するとき、利用可能な記憶領域を共通変数として定義して記録することで、同時に複数のプロセスが共通変数にアクセスできないようにしてプロセスの競合を管理するなどがある。
もし単純に共通変数だけで管理すると、2つのプロセスが都合のいいタイミングで共通変数を書き変えできるので、2つのプロセスの処理のタイミングによっては共通変数の値が2つのプロセスで違う値となるなど、矛盾が出てくることになってしまう。
例えば、プロセスAでは最終的な共通変数の値が3なのに、プロセスBでは最終的な共通変数の値が5になるといった矛盾が発生してしまう。
共通変数の値に矛盾が起こらないようにするためには、各プロセスが共通変数の変更を自由にできないように制限し、この共通変数に対する処理が分割されないようにする。
共通変数の変更を複数のプロセスで同時にできないようにする。同時に一つのプロセスしか実行できないように制限する(共通変数の値に矛盾が生じないよう必要な命令を一つの単位にまとめることも含まれる)。
・上記のようにプログラム全体の中で分割してはならない部分のプログラムを、「クリティカルセクション」または「クリティカルリージョン」と呼ぶ。
・共通変数へのアクセスを同時に1つのプログラム(プロセス)に制限することを、「相互排除」、「排他制御」と呼ぶ。
プロセス競合は、他のプロセスの存在を知っている必要はあるけど、他のプロセスの存在は、そのプロセスが処理を行うために必要なものじゃないことが上記から分かります。
プロセス強調のイメージ
例)
プロセスAとプロセスBは一つのプログラムを役割で分割されたもので、メッセージを入れるボックスを共有するとする。
プロセスA:メッセージを入れる役割
プロセスB:メッセージを取り出す役割
メッセージボックスに入れられるかどうかのフラグ:
真偽の値をとる共通変数にする。Trueならボックス内にメッセージあり。Falseならボックス内にメッセージなし。
プロセスAは共通変数を見て、Falseならメッセージをボックスに入れられると判定し、ボックスにメッセージを入れる。
プロセスBは共通変数を見て、Trueならメッセージをボックスから取り出せると判定し、ボックスからメッセージを取り出す。
上記のように、もともとはひとつのプログラムを2つのプロセスに分割している感じのイメージで、2つのプロセスは共通の目的を達成するためのものであり、メッセージの出し入れは相互のプロセスを処理するために必要であるから、プロセスの協調と呼ぶ。
また、上記のような機構はオペレーティングシステムにおいては「メッセージ転送」または「メッセージ交換」と呼ばれる。
プロセス干渉のイメージ
プロセス干渉は、プロセスが他のプロセスを一時的に強制停止させるような動作。
メモリの中の小さな空き領域を大きな空き領域にするためにメモリの中でプログラムを動かしたり(メモリコンパクションという)、プログラムをメモリからSSDなどの二次記憶に追い出したり(スワップアウトという)する際に、プロセスの干渉が生じる。
例えば、プロセスAが新たな記憶領域を要求すると、プロセスBが処理を一時中断されてスワップアウトされるなどの場合が干渉の例。
→プロセスAが記憶領域を開放したら、プロセスBが処理を再開できる。
プロセス干渉は、一時停止されたプロセスは一時停止を要求したプロセスの存在を認識してなく、一時停止させられていることも認識していないことが特徴。