C++ 多线程 - 线程安全代码
C++ Multithreading - Thread safe code
我正在开发一个从 .dll 运行的游戏引擎。在内部,有一个导出函数 returns 对其中声明的静态 class 的引用,如下所示:
__forceinline __declspec(dllexport) STATE* NF3DGetEngineState(void)
{
static STATE s_State;
return &s_State;
}
其中 STATE
是一个 class,它管理所有组件并具有通过关键部分访问它们的函数:
void Set(int val)
{
EnterCriticalSection(&CriticalSection);
ClassMember = val;
LeaveCriticalSection(&CriticalSection);
}
其中 "CriticalSection" 是 STATE
class 的 CRITICAL_SECTION
成员,当然会被初始化。我使用这些函数的上下文是:
NF3DGetEngineState()->Set(10);
问题是:这段代码线程安全吗?
据我了解,返回对静态声明的引用不是线程安全的。
我该怎么做才能做到这一点?
你的 C++ 版本是哪个?如果它是 C++11 或更高版本,那么代码就尽可能地是线程安全的。如果是 pre-11,那么第一次调用 NF3DGetEngineState
.
是不安全的
澄清。
不是返回对静态变量的引用'is not thread safe'。相反,它是100%安全的。不是线程安全的 C++11 之前的是静态变量初始化本身。 C++11 之前的版本不对函数的首次并发调用做出任何保证。事实上,如果您第一次并发输入此函数,我使用的所有 pre-11 C++ 编译器都会出现问题。原因是,编译器在使用静态变量时生成的代码大致如下所示:
static bool static_var_initialized = false;
if (!static_var_initialized) {
new (&static_var) StaticVarType(); // Explicit constructor call
static_var_initialized = true;
}
显然,如果在静态变量设置为真之前多次调用此函数,则存在多次调用构造函数的可能性。
在C++11中,保证它永远不会发生,构造函数只会被调用一次。它还保证没有线程会看到未构造的值。
我正在开发一个从 .dll 运行的游戏引擎。在内部,有一个导出函数 returns 对其中声明的静态 class 的引用,如下所示:
__forceinline __declspec(dllexport) STATE* NF3DGetEngineState(void)
{
static STATE s_State;
return &s_State;
}
其中 STATE
是一个 class,它管理所有组件并具有通过关键部分访问它们的函数:
void Set(int val)
{
EnterCriticalSection(&CriticalSection);
ClassMember = val;
LeaveCriticalSection(&CriticalSection);
}
其中 "CriticalSection" 是 STATE
class 的 CRITICAL_SECTION
成员,当然会被初始化。我使用这些函数的上下文是:
NF3DGetEngineState()->Set(10);
问题是:这段代码线程安全吗?
据我了解,返回对静态声明的引用不是线程安全的。
我该怎么做才能做到这一点?
你的 C++ 版本是哪个?如果它是 C++11 或更高版本,那么代码就尽可能地是线程安全的。如果是 pre-11,那么第一次调用 NF3DGetEngineState
.
澄清。
不是返回对静态变量的引用'is not thread safe'。相反,它是100%安全的。不是线程安全的 C++11 之前的是静态变量初始化本身。 C++11 之前的版本不对函数的首次并发调用做出任何保证。事实上,如果您第一次并发输入此函数,我使用的所有 pre-11 C++ 编译器都会出现问题。原因是,编译器在使用静态变量时生成的代码大致如下所示:
static bool static_var_initialized = false;
if (!static_var_initialized) {
new (&static_var) StaticVarType(); // Explicit constructor call
static_var_initialized = true;
}
显然,如果在静态变量设置为真之前多次调用此函数,则存在多次调用构造函数的可能性。
在C++11中,保证它永远不会发生,构造函数只会被调用一次。它还保证没有线程会看到未构造的值。