【发布时间】:2011-06-20 05:46:47
【问题描述】:
您好,我创建了一个服务器程序,它在接受套接字连接后分叉一个新进程。 程序中定义了几个静态分配的全局变量。我的问题是这些静态缓冲区在分叉后分配了两次吗?还是叉子只复制堆和调用堆栈上的地址空间?
【问题讨论】:
标签: c linux memory fork shared-memory
您好,我创建了一个服务器程序,它在接受套接字连接后分叉一个新进程。 程序中定义了几个静态分配的全局变量。我的问题是这些静态缓冲区在分叉后分配了两次吗?还是叉子只复制堆和调用堆栈上的地址空间?
【问题讨论】:
标签: c linux memory fork shared-memory
整个地址空间被复制,包括所有全局变量和程序文本。
【讨论】:
main 之前完成。所以内存是进程映像的一部分,这是 fork 复制的。
fork() 复制整个过程映像。所有的。因此,它们是否被分配了两次......不,它们被分配一次,每个可执行映像现在有两个,不,如果您在父级中引用一个,它不会包含与孩子,除非你使用共享内存。
在static 上,该关键字的意思是(来自 ISO C99):
声明了标识符的对象 具有外部或内部联系,或 使用存储类说明符 static 具有静态存储持续时间。 它的生命周期是整个执行 程序及其存储的值是 只初始化一次,之前 程序启动。
这基本上意味着您的缓冲区将作为 CRT 启动例程的一部分初始化一次,并且该空间仅在您退出时消失。在这种情况下,当每个孩子退出时,该存储空间就会消失。
【讨论】:
在fork(2) 期间,整个地址空间被“复制”了。它通常通过 copy-on-write 完成,还有更多关于共享程序文本和库的详细信息,但这与这里无关。父进程和子进程最终都拥有自己的静态数据副本。
【讨论】:
Linux 使用称为写时复制的机制。这基本上意味着,只要变量未被修改,父进程和新进程就共享一个变量。但是在修改变量之前,它被复制并且新进程使用复制。这样做是出于性能原因,技术称为惰性优化。因此,您不必担心在一个进程中更改变量会在另一个进程中更改它。
【讨论】: