2011-02-02 45 views
8

嗨我创建了一个服务器程序,它在接受套接字连接后分叉一个新的进程。 在程序中定义了几个静态分配的全局变量。我的问题是这些静态缓冲区后分配两次?还是叉只重复堆和调用堆栈上的地址空间?C静态变量和linux fork

回答

10

整个整个地址空间是重复的,包括所有全局变量和程序文本。

+0

我正在使用大约10MB的RAM,并且在拨号后没有看到可用内存下降的数量?如果静态分配在编译时发生,那么fork如何复制它? – 2011-02-02 20:10:39

2

fork()重复整个过程映像。所有的。因此,它们是否被分配两次......不,它们被分配一次,每个可执行映像现在有两个,而不是,如果您引用父级中的一个,它将不会保留与孩子,除非你使用共享内存。

static,该关键字是指本(来自ISO C99):

其标识符被声明 与外部或内部的键,或者 与存储类说明一个目的 静态具有静态存储持续时间。 它的使用寿命是程序的整个执行 并且它的存储值是 只有在 程序启动之前初始化一次。

这基本上意味着您的缓冲区将作为CRT启动例程的一部分初始化一次,并且该空间在您退出时仅会消失。在这种情况下,当每个孩子退出时,该存储消失。

6

整个地址空间在fork(2)期间是“重复的”。它通常与写时复制完成,并且有关于共享程序文本和库的更多详细信息,但这与此处不相关。父进程和子进程都以自己的静态数据副本结束。

1

Linux使用名为copy-on-write的机制。这基本上意味着,只要变量不是修改父项,新进程就共享一个变量。但在变量被修改之前,它被复制并且新进程使用复制。这是出于性能原因而完成的,技术被称为延迟优化。所以你不应该担心在一个进程中改变变量会改变另一个进程。