我有一个带有父进程和子进程的程序。在fork()之前,父进程称为malloc(),并在其中填充了一些数据。在fork()之后,孩子需要该数据。我知道我可以使用管道,但是以下代码似乎可以工作:
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> int main( int argc, char *argv[] ) { char *array; array = malloc( 20 ); strcpy( array, "Hello" ); switch( fork() ) { case 0: printf( "Child array: %s\n", array ); strcpy( array, "Goodbye" ); printf( "Child array: %s\n", array ); free( array ); break; case -1: printf( "Error with fork()\n" ); break; default: printf( "Parent array: %s\n", array ); sleep(1); printf( "Parent array: %s\n", array ); free( array ); } return 0; }
输出为:
Parent array: Hello Child array: Hello Child array: Goodbye Parent array: Hello
我知道在子级中可以使用在堆栈上分配的数据,但是似乎在子级中也可以使用在堆上分配的数据。同样,子代不能修改堆栈上父代的数据,子代不能修改堆上父代的数据。因此,我假设孩子获得了自己的堆栈和堆数据副本。
Linux总是这样吗?如果是这样,支持此操作的文档在哪里?我检查了fork()手册页,但没有特别提及堆上动态分配的内存。
谢谢
复制为该进程分配的每个页面(它是具有堆栈或堆的虚拟内存页面),以便派生的进程能够访问它。
实际上,它并非一开始就被复制,而是将其设置为“写时复制”,这意味着一旦其中一个进程(父级或子级)尝试修改要复制的页面,这样它们就不会对彼此造成伤害,并且仍然可以访问fork()处的所有数据。
例如,将实际可执行文件映射到内存中的代码页通常是只读的,因此会在所有分叉的进程中重用- 它们将不会再次被复制,因为没有人在此处写,只能读等等。不再需要写时复制。
可在此处和此处获得更多信息。