在多线程编程中,单例一直是非常难以处理的问题。流行的实现方法都有各种理论上的缺陷:
1. 静态成员变量实现方式
无法保证单例本身的构造和析构时机, 使用有很大限制。包括全局静态变量也是同理
2. 局部静态变量
这个实现很优美,而且是到实际使用时对象才被构建, 但是仍然有很多缺点。
首先, 不能保证多线程安全, 在构建单例时可能发生多线程同时调用构造函数的问题;
其次, 单例析构后, 其他代码仍然可能访问到(例如日志模块), 可能导致难以检测的很严重的问题, 常见的是段错误。(说到这里, 全局静态变量一定要注意, 要么能够确认该函数不会在局部静态变量析构后被调用, 要么使用简单数据类型, 不存在析构后调用出问题的那种)
3. 上锁并两次检验
(其中关于Lock,Guard是多线程常用加锁方式)
这种加锁并两次验证的方式保证了单例的构建安全性,但是仍然有问题: 全局的锁lock本身安全性怎么保证?什么时候delete掉单例?
4. boost::Singleton的实现方式
从理论上保证了不存在安全性问题, 无论是在main()函数调用前还是结束后的任何时候, 访问单例都没有问题, 无须在调用的时候瞻前顾后。但是,也有不足的地方,不能在程序中析构单例。(至于main()调用之前不进入多线程模式,这个应该不成问题)
另外可以扩展着使用:
多线程下安全又完美的单例实现,基本是不可能了。但是可以根据不同情况选择着使用。
附上boost::Singleton实现