C++:同时避免静态初始化顺序问题和竞争条件

2024-01-28

我使用的是 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;
}

然而,我一直在寻找,似乎 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;
}

如果您不能使用 C++2011,您可能想查看系统的底层设施。对于 POSIX 这将是pthread_once()。我不知道其他平台是如何做到这一点的。

也就是说,我推荐not使用它是因为它本质上是某种形式的全局数据,并且通常没有充分的理由使用它。也有例外,但很少见。实际上极其罕见。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++:同时避免静态初始化顺序问题和竞争条件 的相关文章

随机推荐