0

我对 fork() 如何从父进程复制内存感到非常困惑。我试图通过写一个例子来找出它:

int global_var = 0;


int main(int argc, char* argv[]){

    int local_var = 1;

    pid_t child;

    child = fork();


    if (child < 0){
        cout << "Fork error: " << strerror(errno) << endl;
        return 1;
    }



    if (child != 0 ){ // parent


        cout << "Parent: global address: " << &global_var << endl;
        cout << "Parent: local address: " << &local_var << endl;

        ++global_var;
        ++local_var;

        cout << "Parent: global: " << global_var << endl;
        cout << "Parent: local: " << local_var << endl;



    }else{

        cout << "Child: global address: " << &global_var << endl;
        cout << "Child: local address: " << &local_var << endl;

        sleep(1);

        cout << "Child: global: " << global_var << endl;
        cout << "Child: local: " << local_var << endl;
    }

    return 0;

}

我看到了结果:

父:全局地址:0x6021a0 父:本地地址:0x7fff942dd99c 父:全局:1 父:本地:2 子:全局地址:0x6021a0 子:本地地址:0x7fff942dd99c 子:全局:0 子:本地:1

为什么即使孩子的变量与父母的地址相同,孩子也没有看到变量的变化。有人可以帮我解释一下吗。

提前致谢。

4

3 回答 3

1

孩子和父母不共享内存。地址具有相同的值,但它们位于不同的堆栈中,例如两个不同城市的“123 Main Street”;它们指的是内存中的两个不同位置。孩子看不到父母所做的更改,因为这些更改没有发生在孩子的堆栈中。

于 2013-10-16T03:31:13.533 回答
0

进程有两种类型的虚拟内存:内核和用户。当你 fork() 时,你创建了一个克隆的子进程,它具有与父进程几乎相同的独立虚拟内存。fork() 调用在父级中进行,但返回两次,一次在父级中,一次在子级中。这些情况由返回码区分:

int x = fork();
if(x == 0) 
{
    // we are in the child
}
else
{
    // we are in the parent
}

除了此返回代码外,用户内存将是相同的。内核内存有一些区别:定时器在子进程中休息,pid 和 ppid 不同等。通常在子进程中调用 execve() 来跟进,这将覆盖用户区域并允许子进程执行与父级完全不同的代码。execve() 被调用一次并且永远不会返回,因为代码被覆盖,例如

int x = fork();
if(x == 0) 
{
    // we are in the child
    execve("myprog", argv, envp);  // overwrites the code with that from myprog
    // never get here because execve never returns
}
else
{
    // we are in the parent
}
于 2013-10-30T21:10:22.410 回答
0

当你 fork 一个进程时,它成为它自己的程序,即父进程的副本。

在您的示例代码中,您只会在父进程中增加 global_var 和 local_var。

试试这个看看。

int global_var = 0;

int main(int argc, char* argv[]){
int local_var = 1;

pid_t child;

child = fork();


if (child < 0){
    cout << "Fork error: " << strerror(errno) << endl;
    return 1;
}



if (getpid() != 0 ){ // parent
    cout << "Parent: global address: " << &global_var << endl;
    cout << "Parent: local address: " << &local_var << endl;

    ++global_var;
    ++local_var;

    cout << "Parent: global: " << global_var << endl;
    cout << "Parent: local: " << local_var << endl;



}else if(getpid() == 0){ // child

    cout << "Child: global address: " << &global_var << endl;
    cout << "Child: local address: " << &local_var << endl;

    ++global_var;
    ++local_var;

    cout << "Child: global: " << global_var << endl;
    cout << "Child: local: " << local_var << endl;
}

return 0;

}

希望这会有所帮助,fork 有时会令人困惑。

于 2013-10-16T03:48:00.083 回答