使用fork:从父级访问子进程内存

时间:2014-09-29 04:08:17

标签: c arrays memory fork shared

我在C中使用fork()来分解运行本地数组的工作,让每个进程运行一半,然后将数组中每个点的数字相乘,然后将产品设置为第三个阵列。

pid_t  pid;
pid = fork();

if (pid == 0){
    for (i=1; i<((SIZE/2)+1); i++)
    {
        output[i] = (one[i] * two[i]);
    }
    exit(0);
}
else{
    wait(NULL);
        for (i=((SIZE/2)+1); i<(SIZE+1); i++)
        {
            output[i] = one[i]*two[i];
        }         
}

但是,当我在这段代码之后打印产品数组时,我只收到父进程设置的部分,我假设这是因为子进程正在存储它。在打印产品阵列时父母无法获取的内存中的其他值,但我并不完全确定。提前感谢您的帮助。

2 个答案:

答案 0 :(得分:5)

似乎你的叉子与线程混淆了。

分叉复制整个过程。分叉并不像解雇一个线程(它很相似,但线程共享进程内存,分叉复制进程内存)。 fork之后所做的更改不会在父级或子级之间共享。如果要在使用fork()的UNIX上共享父节点之间的内存,则需要设置共享内存段并将该数组放入该内存中。如果你想坚持使用fork语义,Lookup共享内存(shmgetsmctl)。

forking有其用途,但它是一种较旧的传统多处理API,在大多数情况下已被多线程取代。分叉新进程比创建新线程要昂贵得多,即使fork在支持它的现代操作系统上进行了优化。 fork()最常见的用途可能是创建守护进程(fork + parent exit)或执行命令(pipe + fork + exec),就像执行popen()调用一样。

如果使用C,您应该查看pthreads API或其他支持系统线程的线程库。当然,看看你的预期任务,你仍然可以使用fork,但是一旦你掌握了线程,除了使用带有共享内存的fork之外,它并不复杂,除非你实现的算法很复杂。 / p>

答案 1 :(得分:3)

当您进行分叉时,新的子进程会获得父级地址空间的副本。它是完全独立的。如果您需要在父级和子级之间进行通信,则需要使用管道,共享内存等。

注意:在任何现代Linux中,子页面的表都指向所有父页面,并且两个页面的表项都标记为“copy on write”。因此,这两个进程实际上都在查看相同的物理内存。但是,只要任一进程尝试写入内存页,它就会陷阱,然后获取要修改的页面的私有副本。从进程的角度来看,它是相同的,除了fork更快。