私はフォークについて読みました、そして私が理解していることから、プロセスは複製されますが、どのプロセスですか?スクリプト自体またはスクリプトを起動したプロセス?
例えば:
私は自分のマシンでrTorrentを実行していて、トレントが完了すると、それに対してスクリプトを実行します。このスクリプトはWebからデータをフェッチするため、完了するまでに数秒かかります。この間、私のrtorrentプロセスは凍結されます。そこで、以下を使用してスクリプトフォークを作成しました
my $pid = fork();
if ($pid) == 0) { blah blah blah; exit 0; }
このスクリプトをCLIから実行すると、意図したとおりにバックグラウンドで実行されている間、1秒以内にシェルに戻ります。ただし、rTorrentから実行すると、以前よりもさらに遅くなるようです。では、正確には何が分岐したのでしょうか? rtorrentプロセスはそれ自体を複製し、スクリプトはその中で実行されましたか、それともスクリプトはそれ自体を複製しましたか?これが理にかなっていることを願っています。
UNIX環境での高度なプログラミング W. Richard Stevens(pg。188)から:
8.3
fork
関数Unixカーネルによって新しいプロセスが作成されるonly方法は、既存のプロセスが
fork
関数を呼び出す場合です。 (これは、前のセクションで説明した特別なプロセス(スワッパー、init
、およびpagedaemon)には適用されません。これらのプロセスは、ブートストラップの一部としてカーネルによって特別に作成されます。)#include <sys/types.h> #include <unistd.h> pid_t fork(void); /* Returns: 0 in child, process ID of child in parent, -1 on error */
fork
によって作成された新しいプロセスは、子プロセスと呼ばれます。関数は1回呼び出されますが、2回返されます。戻り値の唯一の違いは、子の戻り値が0であるのに対し、親の戻り値は新しい子のプロセスIDであるということです。子のプロセスIDが親に返される理由は、プロセスが複数の子を持つことができるため、プロセスが子のプロセスIDを取得できるようにする関数がないためです。fork
が子に0を返す理由は、プロセスが持つことができる親は1つだけであるため、子はいつでもgetppid
を呼び出して親のプロセスIDを取得できるためです。 (プロセスID 0はスワッパーによって常に使用されているため、0を子のプロセスIDにすることはできません。)子と親の両方が、
fork
の呼び出しに続く命令で実行を継続します。子は親のコピーです。たとえば、子は親のデータスペース、ヒープ、およびスタックのコピーを取得します。これは子のコピーであることに注意してください。親と子はメモリのこれらの部分を共有しません。読み取り専用の場合、親と子がテキストセグメント(セクション7.6)を共有することがよくあります。
Linuxでは、Perlの fork
演算子はシステムの fork
を呼び出し、失敗すると-1ではなくundef
を返します。
Stevensは、継承されたプロパティのリスト(192ページ)と、親プロセスとその分岐した子の違いを示しています。
開いているファイルの他に、子に継承される親のプロパティは他にもたくさんあります。
- 実ユーザーID、実グループID、実効ユーザーID、実効グループID
- 補足グループID
- プロセスグループID
- セッションID
- 制御端末
- set-user-IDフラグとset-group-IDフラグ
- 現在の作業ディレクトリ
- ルートディレクトリ
- ファイルモード作成マスク
- 信号マスクと配置
- 開いているファイル記述子のclose-on-execフラグ
- 環境
- 接続された共有メモリセグメント
- リソース制限
親と子の違いは
fork
からの戻り値- プロセスIDが異なります
- 2つのプロセスの親プロセスIDは異なります。子の親プロセスIDが親です。親の親プロセスIDは変更されません
tms_utime
、tms_stime
、tms_cutime
、およびtms_ustime
の子の値は0に設定されます- 親によって設定されたファイルロックは子に継承されません
- 保留中のアラームは子に対してクリアされます
- 子の保留中のシグナルのセットは空のセットに設定されます