你好,我创建了一个服务器程序,在接受套接字连接后fork出一个新的进程。 程序中定义了一些静态分配的全局变量。我的问题是在fork之后这些静态缓冲区会被分配两次吗?还是fork只会复制堆和调用栈上的地址空间?
你好,我创建了一个服务器程序,在接受套接字连接后fork出一个新的进程。 程序中定义了一些静态分配的全局变量。我的问题是在fork之后这些静态缓冲区会被分配两次吗?还是fork只会复制堆和调用栈上的地址空间?
整个地址空间都被复制,包括所有全局变量和程序文本。
fork(2)
期间被“复制”。通常使用写时复制技术实现,关于共享程序文本和库的细节不重要。父进程和子进程都拥有自己的静态数据副本。fork()
函数会复制整个进程镜像。就是说,所有东西都会被复制一遍。因此,这些内容并不会被分配两次……它们只是在每个可执行镜像中分配一次,并且如果你在父进程中引用其中一个变量,与子进程中的变量不同,除非你使用共享内存。
关于static
这个关键字,它的意思是(来自ISO C99):
标识符具有外部或内部链接的对象,或者使用存储类别说明符
static
声明的对象具有静态存储持续时间。其生存期是整个程序的执行时期,其存储值仅在程序启动之前初始化一次。
这基本上意味着你的缓冲区将作为CRT启动例程的一部分被初始化一次,只有当你退出时才会消失。在本例中,这个存储空间会在每个子进程退出时消失。
Linux使用一种称为写时复制的机制。这基本上意味着,只要变量没有被修改,父进程和新进程就共享一个变量。但在变量被修改之前,它会被复制,新进程使用副本。这是出于性能原因而进行的操作,并且该技术称为惰性优化。因此,您不必担心在一个进程中更改变量会在另一个进程中更改它。