当需要使用C++11实现线程安全的单例时,我知道唯一正确的实现方法如下:
// header
class Singleton final {
public:
static Singleton& getInstance();
private:
Singleton() = default;
Singleton(Singleton const&) = delete;
void operator=(Singleton const&) = delete;
};
// implementation:
Singleton& Singleton::getInstance() {
static Singleton instance;
return instance;
}
在《C++ Concurrency in Action》一书中,A. Williams写道,自从C++11以来,“初始化被定义为只在一个线程上发生”,因此当需要单个全局实例时,它可以被用作std::call_once的替代方法。我想知道当像上述方式定义Singleton时,其析构函数何时被调用。
标准(ISO/IEC 14882:2011)在§3.6.3的一部分中定义了以下内容:
“已初始化对象的析构函数(即,其生命周期已开始)具有静态存储期和由于从main函数返回而被调用和由于调用std::exit而被调用。”
并且
“调用在cstdlib中声明的std::abort函数将终止程序,而不执行任何析构函数,并且不调用传递给std::atexit()或std::at_quick_exit()的函数。”
那么,在干净的退出(从main函数返回)时,哪个先发生?是否在“调用已初始化具有静态存储期的对象的析构函数”之前或之后停止所有线程?
我知道使用由共享库提供的单例模式是一个坏主意(因为可能在其他可能使用它的部分之前被卸载)。当例如从其他(分离的)线程调用Singleton::getInstance()时会发生什么?那是否可能导致未定义行为,或者所有线程(分离或非分离)是否在调用静态变量析构函数之前被终止/合并?
(为清楚起见:我认为单例模式是一种反模式,但当我必须使用它时,我想知道可能会发生什么坏事。)
Singleton::getInstance
方法,因为它不是静态的,而且你不能创建Singleton的实例,因为你将构造函数声明为私有的。你应该将Singleton::getInstance
设置为静态的。 - Mohitstd::terminate
,而加入的线程则是绝对安全的。此外,你可以避免使用分离的线程,那么你还想知道什么? - xskxzr