メモリ割り当て効率の観点から、fork()
子コードでaの後にexecve()
それを使用してプログラムを実行すると、それを使用せずに実行されるのと同じプログラムよりも効率的ですexecve()
。彼自身の?
素朴な例:
実行されない
[..some father code...]
int i;
if(!fork()) {
sum() //from an #include "porg.h"
}
そして実行
[..some father code...]
if(!fork()) {
execve("sum", NULL, NULL); //sum is a program which executes i=2+3
}
2つ目はメモリ割り当ての面で優れていますか?私のプロセスの全体的な仮想アドレス空間を置き換える方が良いですか、それとも完成したオペランドの点で#include "prog"に含まれる他のプログラムの関数を呼び出して上記のコードを実行する方が良いですか?プログラムの実行中にメモリが運ばれますか?
答え1
最初のフラグメントのコードにはif
追加と割り当てが含まれています。それは何よりも簡単で、機械語コードから約2つの命令にコンパイルされます。
2番目には、スタックにロードされ、プッシュされた複数のパラメータ、関数呼び出し、パラメータをシステム呼び出しの正しい場所に移動するlibcのいくつかの内部処理、およびシステム呼び出し自体があります。
システムコールはカーネルモードに移行し(システムによってどのような費用がかかります)、カーネルを調べて実際に処理されたシステムコールを見つけて、プログラムを実行する必要がありますsum
。プログラムを実行するには、プログラムを含むファイルを探し、それをメモリにロードし(おそらくディスクを待っています)、プログラムの各部分がメモリ内の場所を知るためにELFヘッダを解釈し、いくつかのメモリマッピング(おそらくページテーブル)を設定する必要があります。 .. .
私はあなたがアイデアを得ると思います。
答え2
そのような仮定は正しくありません。分岐された子プロセスも子プロセスもsum
明示的にヒープを使用しません。ただし、sum
Cランタイムはプログラムの起動時にいくつかのヒープ構造を初期化できます。スタックにも同様の可能性があります。
しかし、これは考える価値がある妥当な質問です。子プロセスの実行中に親プロセスもメモリを変更すると、子プロセスは変更されたすべてのメモリのコピーをホストします(記録中にコピー)。通常、子はサブタスクを実行し、そのデータのサブセットのみを使用します。
これは、大規模な親プロセスと長期間実行される子プロセスにとって重要です。