我正在使用Windows XP/Visual C++ 2008.
我遇到了一个C++静态初始化顺序问题,我已经用众所周知的"首次使用的构造"成语解决了这个问题:
Foo foo; // Forget this
Foo &foo() // Do this instead
{
// Use ptr, not reference, to avoid destruction order problems
static Foo *ptr = new Foo();
return *ptr;
}
Run Code Online (Sandbox Code Playgroud)
但是,我一直在搜索,看起来Windows(我的平台)并不保证本地静态的线程安全,尽管它确实为全局静态提供了保证.
所以,如果我使我的对象全局化,我得到线程安全但我有初始化顺序问题.如果我使用"首次使用时构造",我会避免初始化顺序问题,但我会遇到竞争条件.我怎样才能同时解决这两个问题?
在C++ 2011中,您使用std::call_once()
:
#include <mutex>
void initialize(Foo*& ptr)
{
ptr = new Foo();
}
std::once_flag flag
Foo& foo()
{
static Foo* ptr(0);
std::call_once(flag, initialize, std::ref(ptr));
return *ptr;
}
Run Code Online (Sandbox Code Playgroud)
如果您不能使用C++ 2011,您可能希望查看系统的基础设施.对于POSIX,这将是pthread_once()
.如何在其他平台上完成我不知道的事情.
也就是说,我建议不要使用它,因为它本质上是某种形式的全局数据,并且通常没有充分的理由使用它.有例外,但很少见.实际上非常罕见.
归档时间: |
|
查看次数: |
1047 次 |
最近记录: |