【发布时间】:2018-08-21 20:59:41
【问题描述】:
首先是代码:
#pragma once
#include <type_traits>
// assign unique identifiers to types
template<typename ...>
class Family
{
static std::size_t identifier() noexcept
{
static std::size_t value = 0;
return value++;
}
template<typename ...>
static std::size_t family() noexcept
{
static const std::size_t value = identifier();
return value;
}
public:
using family_type = std::size_t;
template<typename ... Type>
static family_type type() noexcept
{
return family<std::decay_t<Type>...>();
}
};
// usage
using introspection_family = Family<struct IntrospectionRegistry>;
template<typename Structure>
void addIntrospectData(DataType introspection[MAX_TYPES], DataType const& dataType)
{
/* reserve index for this type in the introspection register */
const auto num = introspection_family::type<Structure>();
assert(num < MAX_TYPES);
introspection[num - 1] = dataType;
}
这段代码为每种类型提供一个整数,我在某种 C++ 内省实现中使用它。
应用程序不是多线程的。
当我在-O0 中编译它时,有时,对introspection_family::type<Structure>() 的调用会在__cxa_guard_acquire@plt 处阻塞,我会遇到死锁。
当使用-O3编译时,我没有任何问题,但这可能只是因为它变得非常难以重现。
__cxa_guard_acquire 用于确保在我们访问它之前构造静态变量,但在这里它应该无关紧要,因为我什至不在线程应用程序中。
有人知道为什么会这样吗?
我用:
CXXFLAGS=-std=c++14 -O0 -g3 -pthread -Wall -Wextra -Werror
LDFLAGS= -g -pthread -lGLEW -lGLU -lGL -lSDL2_mixer -lSDL2
我使用gcc(Ubuntu 5.4.0-6ubuntu1~16.04.10)5.4.0 20160609
【问题讨论】:
-
我的问题恰恰是我没有。当我在一个单独的主目录中提取它时,我没有遇到任何死锁。
-
添加 -pthread 不会改变行为。这是我使用的编译标志: CXXFLAGS=-std=c++14 -O0 -g3 -pthread -Wall -Wextra -Werror LDFLAGS= -g -pthread -lGLEW -lGLU -lGL -lSDL2_mixer -lSDL2 我使用 gcc (Ubuntu 5.4.0-6ubuntu1~16.04.10) 5.4.0 20160609
-
@SergeiKurenkov 进程中只有一个线程(但我仍会尽我所能检查互斥锁,因为它确实应该由这个线程持有。)
-
identifier()里面的std::size_t family()是什么?