3

メインプロセスを実行していて、その実行中にいくつかのポインターを初期化し、事前定義された構造のいくつかのインスタンスを作成したとします。

このメインプロセスをフォークすると、ポインタに個別のメモリが割り当てられますか?また、既存の変数の重複インスタンス、この新しいプロセス用に作成されたデータ構造はありますか?

私の要件の例として、以下を考慮してください-

struct CKT
{
  ...
}

main()
{
   ...Some computations with the structure and other pointers.....
   pid_t pid = fork();
   if(pid == 0) //child
   {
       ..some more computations with the structure...but I need a 
       ..separate instance of it with all the pointers in it as well..
   }
   else if(pid > 0) // parent
   {
       ..working with the original instance of the structure..
   }
   // merging the child process with the parent...
   // after reading the data of the child processes structure's data... 
   // and considering a few cases...
}

誰かが私がこれを達成する方法を説明できますか?

4

5 に答える 5

3

はい。ただし、古いプロセスのメモリスペースをすぐにはコピーしない場合があります。OSは、可能な場合はコピーオンライトを使用し、いずれかのプロセスで最初に変更されたときに各メモリページをコピーします。

COWは、fork(すぐexecに子供に続く)1つの一般的な使用を効率的にするものです。子プロセスは、親から継承されたメモリ空間のほとんどを実際に使用することはありません。

新しいプロセスのコピーは、古いプロセスの場合とまったく同じ数値アドレスを持つため、古いプロセスからのすべてのポインターは、新しいプロセスでも有効なままであり、新しいプロセスのオブジェクトを指します。これは仮想メモリのポイントの一部であり、異なるプロセスが同じポインタ値を使用して異なる物理メモリを参照できるようにします。

于 2012-11-08T10:17:08.220 に答える
3

ポインタとメモリの内容は両方とも、フォークの子に対して複製されます。

すべての種類のデータポインタ、メモリ、変数は、forkで作成された子プロセス用に別のメモリに複製されます。また、プロセスの子から直接ポインタやメモリコンテンツを変更することはできませんでした。

ただし、メモリ共有を使用して、親プロセスの変数を子プロセスから変更できます

このリンクを参照して、その方法を確認してください。プロセスfork()間でメモリを共有する方法は?

于 2012-11-08T10:45:42.450 に答える
2

はい、理論的には、forkシステムコールは、とりわけ親のスタックを複製します。それ以外の場合、実際には、コピーオンライトという名前の一般的な方法があり、その場合に使用されます。

これは、子のプロセスがこのメモリスペースを変更しようとしている場合にのみ、特定の親のメモリページをコピーすることで構成されます。これにより、forkシステムコールのコストを削減できます。

コピーではないものの1つは、子の戻り値fork:0と、父親の子のPIDです。

于 2012-11-08T10:17:33.923 に答える
1

はい、フォークされたプロセスは、すべてのプライベートにマップされたメモリのコピーmallocを受け取ります(、、スタックフレーム、callocグローバル変数を介したデフォルトのメモリマッピング)

お子様は、開いているすべてのファイル記述子の共有コピーを受け取ります。これらのファイル記述子は、親と子の両方が閉じるまで有効で開いたままになることを意味します。これらのファイル記述子のシークも共有されます。ファイル記述子を子プライベートにしたい場合は、それを行う必要がありますfdreopen。それ以外の場合は、forkの直後に、子で不要なすべてのファイル記述子を閉じることを強くお勧めします

あなたの子供は同じ記憶の共有 MAP_SHAREDマッピングを受け取ります。それらは、親と子の間で共有される同じ物理メモリに引き続きアクセスします。shm*これは、一連の呼び出しおよびmmapで取得されたすべての共有メモリに適用されますMAP_SHARED

お子様は、を介してフラグでマークされたマッピングを受け取りませ。それらは子供では無効になります。これはデフォルトの動作ではなく、明示的に使用されない限り、心配する必要はありません。MADV_DONTFORKmadvise

于 2012-11-08T10:56:56.187 に答える
0

共有メモリセグメントを使用すると、探している結果が得られる場合があります。システムコールを使用mmapして共有メモリセグメントを作成し、すべての共有構造をそのセグメントに配置します。このセグメントでは使用できないためmalloc(システムコールによってセグメント全体へのポインタとして返されます)、構造を手動でコピーし、共有メモリ使用量の追跡を自分で行う必要があります。

おそらく、最初にデータをローカルに割り当ててから、それらが使用しているメモリの量を評価し、正しいサイズで共有メモリの割り当てを行うことができます。共有セグメントをより大きなサイズに再割り当てすることもできます。その場合、一方の端からもう一方の端に何らかの方法で再割り当てを通知する必要があります(おそらく、共有マップが指す最初の整数を使用してその値を格納しますか?)。

マニュアルページ:

于 2012-11-08T16:17:38.690 に答える