【OS】forkとexecの違い ざっくりまとめ
はじめに
プログラミングやOSの学習をしているとよく出てくる「fork」と「exec」という言葉について難しいと感じことはありませんか?
どちらもプロセスを扱うシステムコールですが、役割や使い方がまったく異なります。
本記事では、2つの違いをわかりやすくまとめていきます。
プロセスとは
OS上で動作している実行中のプログラムのことを指します。
プロセスには、メモリ空間、PID(プロセスID)、実行状態などの情報が紐づいています。
forkとは
fork() は、現在のプロセスをそっくりそのままコピーして新しいプロセス(子プロセス)を作るためのシステムコールです。
親プロセスとまったく同じコードとデータを持つプロセスが作られます。
PIDは親と子で異なります。さらに、親と子は並行して動作が可能(並列処理が可能)です。
execとは
exec() は、現在のプロセスを、指定した別のプログラムで上書きするシステムコールです。
exec() を呼び出すと、現在のプログラムは完全に消え、新しいプログラムに置き換わります。
PID は変わりません(プロセスは同じだが中身が変わる)。また、fork() と併用するのが一般的です。
具体例:「ターミナルでコマンドを実行する」
ターミナルで ls -l
を実行したときを考えてみましょう。
全体のワークフローイメージ
※https://www.coins.tsukuba.ac.jp/~syspro/2018/2018-05-09/index.html より
① bash(シェル)がフォークする
シェルは自分自身をコピーして子プロセスを fork() で作ります。
・親:bash(シェル本体)
・子:bashのクローン(まだ中身は同じ)
② 子プロセスが ls コマンドを実行する(exec)
子プロセスは exec() を使って、自分のプログラム内容を ls に置き換えます。
ここで、子プロセスの中身は bash ではなく ls になります。
③ 子プロセス(ls)が実行される
この時点で、CPU上では ls プログラムが動いており、結果が標準出力(端末)に表示されます。
④ ls 終了 → 親のbashに戻る
ls が終了すると、子プロセスは exit() して終了し、親プロセス(シェル)に制御が戻ります。
このように、fork してから exec するのは、UNIXの設計思想によるものです。
fork() でプロセスを分けることで、親と子の独立性を保ち、
exec() で別のプログラムに入れ替えることで、動的にコマンドを実行しています。
これにより、シェル本体はそのまま残しつつ、任意のコマンドだけを新しく実行できるという柔軟な仕組みになっています。
まとめ
fork と exec は、UNIX/Linux におけるプロセス制御の基本であり、この2つを理解することは、OSの仕組みやプロセスのライフサイクルを正しく捉える第一歩となるでしょう。
最後までお読みいただき、ありがとうございました。
参考・画像引用元URL
Discussion