1

Say I have a meyers singleton

Data& get() {
  static Data data = initialization_work();
  return data;
}

that's already been used and initialized in a parent process. I then fork(2) a child process, and in the child process data may need to be different (ie, i'd like initialization_work() to rerun the first time get() is called in the child).

First, will data automatically be reinitialized in the forked child? My suspicion is no, based on my mediocre knowledge of linux (forked child VA space is a duplicate of parent mapped to physical memory copy-on-write, so i assume child process will see data as already initialized and won't redo initialization_work()) and a couple other questions (C static variables and linux fork, C++ static variable and multiple processes).

Second, if data will not be reinitialized in the child by default, is there a way to force reinitialization the first time the child calls get()? If not, I can try to figure out some other pattern (and I'd really appreciate any suggestions on what pattern might fit this use case).

Michael Carilli
  • 371
  • 2
  • 12
  • @MartinYork: 1. The process ID is different :-P 2. The question still stands, even if it's about the original process... – einpoklum Apr 08 '21 at 20:38
  • I answered before I should (so I removed it). Do you _want_ it to reinitialize even if you get a (nearly) exact copy as @MartinYork mentions? – Ted Lyngmo Apr 08 '21 at 20:38
  • 2
    You could save the current `pid` inside `get()` if the pid changes reset that value of `data`? – Martin York Apr 08 '21 at 20:41

1 Answers1

3

First, will data automatically be reinitialized in the forked child? My suspicion is no

Why just a suspicion? Indeed, nothing will be initialized. As @MartinYork mentions - you get a copy of the original process. That's the magic of forking - no need to initialize the world. The parent and the child both proceed to act differently based (almost) only on the return value of the fork() call.

Second, if data will not be reinitialized in the child by default, is there a way to force reinitialization the first time the child calls get()?

That's the same question as asking about forcing a reinitialization of a singleton in the original process. Now, of course there are ways...

einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • Use `std::optional` to take care of all the placement-new and explicit destructor call details. – Ben Voigt Apr 08 '21 at 21:58
  • @BenVoigt: That's a great idea too. Edited it in. – einpoklum Apr 08 '21 at 22:11
  • Seems to me whether i use std::optional or not, the child needs to know it's the child to destruct and reconstruct `data`, so I'd need to check the PID or something. is that implicitly part of your suggestions? – Michael Carilli Apr 08 '21 at 23:41
  • 1
    @MichaelCarilli: But the child process does know it's the child, based on the result of the `fork()`; that's what you check. – einpoklum Apr 09 '21 at 08:27
  • Right, I meant given its importance, it should be explicit in the answer for future readers. I see you added it, thanks! – Michael Carilli Apr 10 '21 at 19:49