C++ 在静态函数中,使静态本地对象线程安全的有效方法是什么?

C++ 在静态函数中,使静态本地对象线程安全的有效方法是什么?,c++,visual-studio-2013,static,thread-safety,msvc12,C++,Visual Studio 2013,Static,Thread Safety,Msvc12,我正在分析一个崩溃转储,发现在本地静态对象初始化中存在竞争条件。我使用的是MSVC++12.0,它没有线程安全的静态初始化 这是程序的最低版本 #include <iostream> #include <thread> #include <chrono> #include <Windows.h> class internalClass { public: internalClass(int parm) : value(parm) {}

我正在分析一个崩溃转储,发现在本地静态对象初始化中存在竞争条件。我使用的是MSVC++12.0,它没有线程安全的静态初始化

这是程序的最低版本

#include <iostream>
#include <thread>
#include <chrono>
#include <Windows.h>

class internalClass
{
public:
    internalClass(int parm) : value(parm) {}
    int value;
};

class externalClass
{
public:
    externalClass(int parm)
    {
        Sleep(1000*10);
        dp = new internalClass(parm);

    }
    void print()
    {
        std::cout << dp->value << "\n";
    }
    ~externalClass()
    {
        delete dp;
    }
    internalClass *dp;
};

static void foo()
{
    static externalClass obj(50);
    obj.print();
}

int main()
{
    std::thread t1(foo);
    Sleep(1000);
    std::thread t2(foo);
    t1.join();
    t2.join();
}
#包括
#包括
#包括
#包括
类内部类
{
公众:
internalClass(int parm):值(parm){}
int值;
};
类外部类
{
公众:
外部类(内部参数)
{
睡眠(1000*10);
dp=新的内部类别(parm);
}
作废打印()
{

std::cout value您可以通过确保在启动线程之前第一次调用
foo
来避免线程安全问题。在创建第一个线程之前,从
main
调用
foo
。在这种情况下,您可能希望添加一些不调用
obj.print()
当你这样做的时候。静态成员变量是线程安全的吗?这样我就可以把静态变量作为classIf的一部分。如果我把externalClass作为静态对象放在一个类中,那么它就会在线程启动之前被初始化。这种方法有什么问题吗?@nonock你能分享一些使用atomic构造对象的例子吗?我所看到的是在整型上使用原子静态成员变量(或全局变量)将在
main
开始执行之前初始化。此时通常不考虑线程问题,除非某些初始值设定项创建线程。在不同转换单元中声明的变量的初始化顺序可能会有问题。通过确保对
foo
的第一次调用是在启动线程之前。在创建第一个线程之前,从
main
调用
foo
。在这种情况下,您可能希望添加一些内容以避免调用
obj.print()
当你这样做的时候。静态成员变量是线程安全的吗?这样我就可以把静态变量作为classIf的一部分。如果我把externalClass作为静态对象放在一个类中,那么它就会在线程启动之前被初始化。这种方法有什么问题吗?@nonock你能分享一些使用atomic构造对象的例子吗?我所看到的是在整数类型上使用原子将在
main
开始执行之前初始化静态成员变量(或全局变量)。此时通常不考虑线程问题,除非某些初始值设定项创建它们。在不同转换单元中声明的变量的初始化顺序可能会有问题。