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).
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...
You get a non-const reference to data
, right? Well, you can destroy it explicitly, then use placement-new on that address. I'm... almost sure that's legit.
@BenVoigt's neat alternative to the above: Use an std::optional<Data>
singleton. It's still a sort-of-a-singleton, but you can assign nullopt
to it, for destruction, then construct a new Data
in place with std::optional::emplace
.
Change the class' code to place the data
variable somewhere more visible.
Just drop the singleton pattern. It is unlikely you really need it. Watch:
Retiring the Singleton Pattern: Concrete Suggestions for What to use Instead
A talk by Peter Muldoon at CppCon'20.