When a thread safe singleton has to be implemented using C++11 the only correct implementation I know is the following:
// header
class Singleton final {
public:
Singleton& getInstance();
private:
Singleton() = default;
Singleton(Singleton const&) = delete;
void operator=(Singleton const&) = delete;
};
// implementation:
Singleton& Singleton::getInstance() {
static Singleton instance;
return instance;
}
In his Book "C++ Concurrency in Action" A. Williams writes that since C++11 "the initialization is defined to happen on exactly one thread" and so this "can be used as an alternative to std::call_once" when a single global instance is required. I wounder when the destructor of the Singleton is called when defined as above.
The standard (ISO/IEC 14882:2011) defines as part of §3.6.3 e. g.
Destructors for initialized objects (that is, objects whose lifetime has begun) with static storage duration are called as a result of returning from main and as a result of calling std::exit.
and
Calling the function std::abort() declared in cstdlib terminates the program without executing any destructors and without calling the functions passed to std::atexit() or std::at_quick_exit().
I know that it is a bad idea to use a singleton that is provided by a shared library (that might be unloaded before other parts that might use it), but is that like not possible when the singleton is statically linked/defined as part of the executable? What happens when Singleton::getInstance() is called e. g. from other (detached) threads? Could that lead to undefined behavior or will all threads (detached or not) be terminated/joined before the destructors of static variables are called?
(To be clear: I think singleton is an anti-pattern, but when I have to use it I want to know the what kind of bad things could happen.)
Aucun commentaire:
Enregistrer un commentaire