【问题标题】:C static variables and linux forkC静态变量和linux fork
【发布时间】:2011-06-20 05:46:47
【问题描述】:

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

【问题讨论】:

    标签: c linux memory fork shared-memory


    【解决方案1】:

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

    【讨论】:

    • 我正在使用大约 10MB 的内存,但在 fork 调用后我没有看到可用内存量下降?如果静态分配发生在编译时,那么 fork 如何复制它?
    • 静态分配不会发生在编译时 - 它发生在运行时,其实现由相关的 C 库决定,但必须在 main 之前完成。所以内存是进程映像的一部分,这是 fork 复制的。
    • @juxtapose:当你 fork() 一个程序时,所发生的只是程序使用的内存被标记为写时复制。因此,在您开始写入内存之前,您的 ram 使用率不会开始上升,然后只有您写入的页面才会被取消共享。
    【解决方案2】:

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

    static 上,该关键字的意思是(来自 ISO C99):

    声明了标识符的对象 具有外部或内部联系,或 使用存储类说明符 static 具有静态存储持续时间。 它的生命周期是整个执行 程序及其存储的值是 只初始化一次,之前 程序启动。

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

    【讨论】:

      【解决方案3】:

      fork(2) 期间,整个地址空间被“复制”了。它通常通过 copy-on-write 完成,还有更多关于共享程序文本和库的详细信息,但这与这里无关。父进程和子进程最终都拥有自己的静态数据副本。

      【讨论】:

        【解决方案4】:

        Linux 使用称为写时复制的机制。这基本上意味着,只要变量未被修改,父进程和新进程就共享一个变量。但是在修改变量之前,它被复制并且新进程使用复制。这样做是出于性能原因,技术称为惰性优化。因此,您不必担心在一个进程中更改变量会在另一个进程中更改它。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-03-29
          • 2013-04-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多