让我们简单地使用clone(2)
int stack_func(void *arg)
{
*(int*)arg = 10;
return 0;
}
int main()
{
int a = 50;
clone(stack_func, malloc(1024*1024) + (1024*1024), SIGCHLD, &a);
sleep(2); //Just to be sure
printf("%d\n", a);
return 0;
}
在clone()
的手册页中,指定父和子两者都可以共享内存,父进程中的printf()
应该打印10而不是50.但是它没有发生。为什么呢?
stack_func
开始,*arg
(不是variable arg
)存储在哪里?arg
的引用时会获得新副本? 答案 0 :(得分:2)
您忘记使用标记CLONE_VM
:
clone(stack_func, malloc(1024*1024) + (1024*1024), SIGCHLD | CLONE_VM, &a);
CLONE_VM (自Linux 2.0开始)
如果设置了 CLONE_VM ,则调用进程和子进程在同一内存空间中运行。特别是,由调用进程或子进程执行的内存写入在另一个进程中也是可见的。此外,子进程或调用进程使用mmap(2)或munmap(2)执行的任何内存映射或取消映射也会影响其他进程。
如果未设置 CLONE_VM ,则子进程在
clone()
时在调用进程的内存空间的单独副本中运行。其中一个进程执行的内存写入或文件映射/取消映射不会影响另一个进程,就像fork(2)一样。
答案 1 :(得分:2)
您需要设置CLONE_VM
标志。来自the Linux man page:
如果设置了CLONE_VM,则调用进程和子进程 在相同的内存空间中运行。特别是,内存写入 由调用进程或子进程执行的 在其他过程中也可见。而且,任何记忆 使用mmap(2)或munmap(2)执行映射或取消映射 孩子或调用过程也会影响其他过程。
如果未设置CLONE_VM,子进程将单独运行 当时调用进程的内存空间的副本 克隆()。执行内存写入或文件映射/取消映射 其中一个进程不会影响另一个进程,如同 叉(2)。
clone(stack_func, malloc(1024*1024) + (1024*1024), CLONE_VM | SIGCHLD, &a);