【问题标题】:C++ static variable and multiple processesC++ 静态变量和多进程
【发布时间】:2012-03-03 11:08:33
【问题描述】:

我有一个 C++ 程序,它派生子进程来做一些工作。在这些子进程中创建了一些类,并且在成员函数中有一个静态变量,如下所示:

void MyClass::foo () {
    static std::string uuid;
    ...
    uuid = "A new value";
}

由于每个进程都是新分叉的,我假设 uuid 总是被初始化为一个空字符串。但是,在某些情况下,我注意到 uuid 在函数的第一个条目时已经被赋予了一个值,这会导致问题。

如何跨分叉进程初始化这个静态变量?我唯一的选择是使用类变量吗?使用静态变量的原因是我不想引入只在单个函数中使用的类变量,以保持类的整洁。

【问题讨论】:

  • 查看答案here
  • MyClass 没有在 fork 之前实例化,但之后没有实例化,所以链接没有回答我的问题。因此,我假设静态变量应始终使用空字符串进行初始化,但情况并非总是如此。这怎么可能?
  • “分叉”是什么意思? C++ 标准中没有这样的东西。如果您指的是其他平台/库,则必须这样说。
  • fork()系统调用中分叉
  • 您的假设是正确的,正如this test 所展示的那样。你描述的结果不能从你描述的情况得出。请发布一个演示问题的简短程序。 sscce.org

标签: c++ static initialization


【解决方案1】:

我发现 MyClass 在极少数情况下也会在父进程中实例化。之后,fork 进程继承已经在父进程中初始化的静态变量。

【讨论】:

    【解决方案2】:

    当第一个进程启动时,二进制可执行文件被映射到内存中,它的不同部分最终都在内存中(.bss、.text 等)。由于数据部分在内存中映射,因此您的静态变量指向映射的 .data 部分的偏移量。

    现在,当一个进程分叉时,创建的进程被授予自己的虚拟内存空间,这是其父进程的完美副本(在分叉时)。 “uuid”指向它自己的内存区域。

    旁注:内核允许子虚拟页面映射到与父页面相同的物理页面,只要两个进程都没有修改它们。

    【讨论】:

      猜你喜欢
      • 2012-09-30
      • 1970-01-01
      • 2013-03-29
      • 1970-01-01
      • 2011-06-03
      • 2011-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多