5

私は "fork()" を初めて使用します。fork() が呼び出されると、現在の (呼び出し元の) プロセスの正確なコピーが開始されることをどこでも読みました。次のコードを実行すると、2 つの異なるプロセスが存在するはずです。変数と関数に割り当てられたメモリ位置。

#include<stdio.h>
int i=10;
int pid;
 int main(){
  if((pid=fork())==0){
    i++;//somewhere I read that separate memory space for child is created when write is needed
    printf("parent address= %p\n",&i);// this should return the address from parent's memory space
  }else{
    i++;
    i++;
    printf("child address= %p\n",&i);// this should return the address of child's memory space 
  }
  wait(0);
  return(0);
 }
出力が次のようになる理由::
子アドレス::804a01c
親アドレス::804a01c

親と子の両方のアドレスが同じなのはなぜですか?

4

3 に答える 3

9

変数と関数に割り当てられた2つの異なるメモリ位置を持っています。

いいえ; Linux は仮想メモリを実装しています。つまり、各プロセスには独自の完全なアドレス空間があります。その結果、 の後fork、両方のプロセスがメモリ内オブジェクトのコピーに対して同じアドレスを参照します。

(余談ですが、VM は物理メモリ内のプロセス間でコードを共有し、すべてのデータはcopy-on-writeのみになります。)

于 2012-03-15T16:58:34.327 に答える
3

アドレスはプロセスローカルです。あるプロセスでは、別のプロセス804a01cと同じではありません。804a01c

于 2012-03-15T16:58:51.220 に答える
2

仮想メモリのため、両方のアドレス空間がそれぞれのプロセスと同一に見えます。それらが格納されている物理メモリは異なります。ただし、実際には、メモリの最適化 (ほとんどのカーネルで実装されている) によって複雑になります。これは、対応する異なる仮想ページを同じ物理ページにマップし、それらのプロセスのいずれかがメモリのそのページに書き込むまで、その時点でページが物理的に複製されます。別の物理アドレスに割り当てます (そして、仮想ページはプロセス用に再マップされます)。

他にも多くの複雑な問題があります。最も認識されているのは、 の戻り値がfork()プロセス間で異なることですが、通常はメモリではなくレジスタ値の違いです。ただし、開いているファイルやその他の一部のリソースは継承不可とマークされる可能性があるため、その他の相違点が存在する可能性があります。マイナーですが、役立つ場合があります。

于 2012-03-15T17:01:08.883 に答える