2014-09-29 143 views
4

我在C中使用fork()来分割通过本地数组运行的工作,让每个进程运行一半,然后乘以数组中的每个点的数字,然后将产品设置在第三个数组中。使用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]; 
     }   
} 

然而,当我这个段的代码我只接收由所述父进程设置的部分之后,打印产品阵列,我假定这是因为子进程将其存储在其他地方的存储器中的值父母在打印产品阵列时无法拾取,但我不完全确定。预先感谢您的帮助。

回答

5

看来你有叉与线程混淆。

分叉复制整个过程。分叉不像是从一个线程中发射出来的(好像它是类似的,但线程共享进程内存,分叉复制进程内存)。父母或孩子之间不共享分支后所做的更改。如果要在使用fork()时在UNIX上分享父和子之间的内存,则需要设置共享内存段并将该数组放入该内存中。查找共享内存(shmget,smctl)如果你想坚持使用fork语义。

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

如果使用C,则应该查看pthread API或某个其他支持系统线程的线程库。当然,看看你想要完成的任务,你仍然可以使用fork,但是一旦你得到了一堆线程,除了使用带共享内存的fork之外,这并不复杂,除非你正在实现的算法很复杂。

+1

我可以添加另一个分叉新进程的有用用法吗?可以在自己的进程中运行可能的错误代码(可能是由于输入错误)或一些测试代码。这样可以保护主进程免受诸如SIGSEGV之类的信号的干扰。父进程仍然可以报告孩子的状态(使用'wait()')。 – 2014-09-29 04:41:44

+0

优秀的第一个答案+1 – 2014-09-29 04:52:15

3

当您分叉时,新的子进程获得父级地址空间的副本。它是完全分开的。如果您需要父母与孩子之间的沟通,则需要使用管道,共享内存等。

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