重複の可能性:
フォーク後、グローバル変数は共有されますか?
私のCプログラムでは、構造体リンクリストをグローバル変数として保持しています。その後、子プロセスをフォークします。リンクリストのノードを解放すると、子プロセスで子プロセスを終了します。ノードは親プロセスでも削除されますか?
私がこれを試していたとき、ノードはまだ親プロセスに残っていたようです...これは正しいですか?なんで?
重複の可能性:
フォーク後、グローバル変数は共有されますか?
私のCプログラムでは、構造体リンクリストをグローバル変数として保持しています。その後、子プロセスをフォークします。リンクリストのノードを解放すると、子プロセスで子プロセスを終了します。ノードは親プロセスでも削除されますか?
私がこれを試していたとき、ノードはまだ親プロセスに残っていたようです...これは正しいですか?なんで?
いいえ、親プロセスでは削除されません。正しいメンタルモデルは、子供が親の記憶の独立したコピーを取得しているということです。2つのプロセスはメモリを共有していません(共有メモリセグメントを明示的に設定してデータをそこに配置しない限り)。
プロセスの代わりにスレッドを使用する場合、状況は根本的に異なります。同じプロセス内で実行されているスレッドは、アドレス空間を共有します。
fork(2)
親仮想アドレス空間のコピーを作成するため、これらstruct
を共有メモリに配置しない限り、これらはまったく関係ありません。
はい、意図したとおりに機能します。親を子から(または子を親から)変更することはできません
2つのプロセス(親と子)は2つの異なるプロセスであり、プロセスの1つが、たとえば、マシン上で実行されているWebサーバーのメモリに書き込むことができないのと同様に、親プロセスは書き込みを行うことができません。子プロセスまたはその逆。
親プロセスのすべてを子プロセスにコピーする必要をなくすために、OSは「コピーオンライト」と呼ばれるものを使用します。これは次のように機能します。「子」プロセスが作成されると、親プロセスを表すページが複製されます。 、および「読み取り専用」とマークされています。書き込みが発生すると、OSはその書き込みをトラップし(メモリは読み取り専用であるため許可されません)、メモリのコピーを作成します。これにより、プロセスはメモリの独自のコピーとしてメモリに書き込みます[そしてマークを外します他のプロセスでは「読み取り専用」であるため、元のメモリコンテンツがあるため、データを変更できるようになります]。
他の人が言っているように、「共有メモリ」(必要に応じて完全に独立したプロセス間で共有することもできます)を使用することでこれを克服できます。