C++ 在静态函数中,使静态本地对象线程安全的有效方法是什么?
我正在分析一个崩溃转储,发现在本地静态对象初始化中存在竞争条件。我使用的是MSVC++12.0,它没有线程安全的静态初始化 这是程序的最低版本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) {}
#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
开始执行之前初始化静态成员变量(或全局变量)。此时通常不考虑线程问题,除非某些初始值设定项创建它们。在不同转换单元中声明的变量的初始化顺序可能会有问题。