【发布时间】:2010-12-12 00:21:21
【问题描述】:
在《Cracking the coding interview》一书的第 259 页上,给出了 C++ 中的模板化单例(我不想发布所有代码,以防其受到版权保护)。
问题是将单例实现为模板,并假设一个名为 Lock 的类确保其线程安全和异常安全。
答案正如您对使用双重锁定技术的单例所期望的那样,Lock 对象具有一个 acquire()/release() 对。
但是该类没有析构函数。这是一个错误吗?如果它有一个析构函数,因为类实例成员是静态的,析构函数只会在程序终止时被调用,如果程序正在终止,任何分配的内存都会被释放回系统。还是会?是否存在这种情况无法发生并且没有析构函数的单例因此导致泄漏的情况?
其次,问题是让单例异常安全。单例对象是使用未捕获的新对象创建的,而 Lock 对象是静态的,因此这实际上是异常安全的吗?如果没有用于创建单例的内存,那么 new 会抛出异常,但是由于 Lock 对象是静态的,因此无法调用其 release() 方法,因此它永远不会被调用?
【问题讨论】:
-
如果一个类没有析构函数,编译器会生成一个默认的。
-
双重锁定的问题在于它以某种方式假定
Lock在第一次尝试获取它之前已正确初始化。但是,如果您尝试在全局构造期间获取它,则情况可能并非如此(在某些编译器上)... C++0x 通过要求编译器使局部静态变量初始化线程安全来解决该问题。 -
这本书充满了错误……而且不仅仅是错别字。很多解决方案都是错误的。这是一个很好的例子。自从多核出现以来,双重检查锁定技术完全是伪造的。
标签: c++