在C++ 11中,以下是线程安全的:

void someFunc()
{
    static MyObject object;
}

但是关于
void someFunc()
{
    static MyObject *ptr = new MyObject();
}

那么这是线程安全的吗?

正如@Nawaz在评论中所提到的,很可能MyObject构造函数不是线程安全的,因此让我们将问题分为几部分:

1)如果ctor是线程安全的(它不访问任何共享状态),那么static MyObject *ptr = new MyObject();是线程安全的吗?换句话说,static int *ptr = new int(0);是线程安全的吗?

2)如果ctor不是线程安全的,但是仅通过从不同线程调用someFunc来创建对象,并且构造函数从未在其他任何地方使用,那么这将是线程安全的吗?

最佳答案

是的,它是线程安全的。这是从与第一个示例相同的保证得出的,该保证是函数的并发执行将只对静态变量进行一次初始化。由于必须将静态指针初始化一次,并且将其初始化方式定义为对new的调用,因此new及其调用的构造函数将分别被调用一次。假设new对象的构造函数没有做任何不安全的事情,那么整个事情将是安全的。

感谢Matthieu M.指出一个异常(exception):如果引发初始化,将在下一次(挂起或将来)调用该函数时再次尝试进行初始化。但是,它仍然是线程安全的,因为第二次尝试直到第一次尝试失败后才开始。

话虽如此,看到这样的代码令人担忧,因为它似乎可能导致内存泄漏,并可能被诸如valgrind之类的自动化工具标记出来,因此最好避免这种情况。甚至具有静态成员的类也可能更好,因为这样,在程序结束之前使用特殊的方法清理静态对象将变得更加容易。

关于c++ - 指向对象初始化线程安全的静态指针,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24933452/

10-10 15:08