C++函数中的多线程静态 POD 初始化
C++ multithreaded static POD initialisation within a function
我不确定静态 POD 是否实际上可能多次初始化为零,如果它们是由多个线程调用的函数中的静态变量:
void CalledByManyThreads()
{
struct StaticClass
{
struct POD { volatile LONG value; } pod; // Using MSVC specific volatile behaviour - I don't care about std::atomic
StaticClass() // Constructor makes the struct a non-POD so we likely need the extra POD struct for our member data
{
while (pod.value == 0)
if (InterlockedCompareExchange(&pod.value, 0, 1) == 0)
{
// Is it possible that another thread zero initialises pod after we have just set it to 1?
break;
}
}
};
static StaticClass test; // When is test.pod zero initialised in MSVC 2013+?
}
围绕这一功能领域,强制性C++标准与编译器的实际行为之间存在差异 - 我更感兴趣的是MSVC2013年以来现有编译器的现实。
是否有可能一个线程将 pod.value 设置为 1,但在另一个竞争线程 0 之后将其初始化回 0?
MSVC 2013 不支持"魔术静力学" MSDN : C++11 支持。 我还在较早的时间验证了生成的代码,并确认它不支持它们。
VS2015似乎工作正常(并标记为这样)。
VS2013 中生成的代码与早期代码相同,具有线程不安全机制,用于检测变量是否已构造。 这是必要的。 这个测试+构造对象的时间是比赛发生的时间长度。
一个项目完全建成后,不再进行重建。
我在VS2013中发现了许多编译器问题(例如,在VM中运行时运行时,运行时库中AVX命令的检测不正确),Microsoft建议针对任何已识别的问题升级编译器。Microsoft连接:AVX 生成非法指令
这是我给你的建议。
是否有可能一个线程将 pod.value 设置为 1,但在另一个竞争线程 0 之后将其初始化回 0?
编译器有 3 个计划用于初始化程序中的静态数据。
- 非常静态的数据
- 静态数据
- 非容器数据。
非常静态的数据
当编译器看到一个在编译时可以完全知道的数据结构时,它将在 obj 文件中为该结构创建内存,该文件将为最终文件提供正确的布局。 这不会多次初始化。
静态数据
如果POD
结构正在使用编译时不完全已知的信息进行初始化,则将为未知元素创建一个构造函数。 在我确定的情况下
struct memoryAllocator {
void * (*mallocFunction)( size_t size );
int initialized;
}
memoryAllocator alloc { malloc, 1 };
ALLOC初始化时初始化设置为1作为静态数据,然后使用导入的malloc的值在main之前构造。 似乎没有C++要求对象的构造是全有或全无。 这对我来说似乎是一个疏忽。
非容器数据
这初始化为构造函数。 在静态函数中,代码由一个变量保护,该变量描述初始化是否已完成。
通过查看您的代码,您有
- 未初始化 POD 结构中的数据
- 不是
value
能够从 1 转换到 0 的编写代码。
在这个术语中,我希望 POD 数据保持未初始化和 0(因为它是静态的),并且构造函数是唯一要调用的项目,并且会将数据修改一次为 1(由于互锁)。
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- #为""定义宏;静态";针对不同的上下文
- cmake如何在fedora工作站中找到boost静态库包
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 将公共但非静态的成员函数与ALGLIB集成
- cmake在我的项目中所需的所有静态库都不成功
- C++从另一个类访问公共静态向量的正确方法是什么
- 基于boost的程序的静态链接——zlib问题
- 在静态库中嵌入类方法
- Qt C++静态thread_local QNetworkAccessManager是线程应用程序的好选择吗
- 如何在C++中获得"静态纯虚拟"功能?
- 私有类型的静态常量成员
- 使用gcc从静态链接的文件中查找可选符号
- 在 .h 文件中的类中声明静态变量和在.cpp文件中声明"global"变量有什么区别
- 指向 POD 类型的指针之间的静态转换与重新解释转换
- C++函数中的多线程静态 POD 初始化
- 函数作用域的静态非 Pod 对象初始化
- 对空的用户定义构造函数将如何初始化非静态非 POD 成员变量感到困惑
- 如何初始化非pod静态值
- 是 POD 静态的默认析构函数