告诉编译器不要对我的 __thread 变量执行析构函数
Tell compiler not to execute destructor on my __thread variable
我特别希望我的一个变量没有构造函数和析构函数。它被定义为这个
struct Dummy { ~Dummy() { assert(0); } };
__thread Dummy dumb;
真正的代码是零初始化,从线程本地内存池中抢内存。该池在 main 的末尾被销毁,因此该析构函数试图访问已释放的内存池。
我可以解决这个问题,但我想以一种干净的方式来解决这个问题。 1) 我可以告诉编译器在所有线程局部(或全局)变量之后释放我的池吗?还是在所有线程局部函数之前对其进行了初始化,以便在适当的时间进行清理?或者更好的是 2) 根本不执行清理?我可以发誓 __thread
不允许 constructors/destructors 所以我很惊讶甚至 运行.
堆栈跟踪显示 __run_exit_handlers
是调用析构函数的函数。它 parents 是 exit
、__libc_start_main
和 start
。这发生在 clang 和 gcc
在我开始回答之前,任何读过这篇文章的人都应该知道这通常是一个非常糟糕的主意,应该作为最后的手段来对待。但是,OP想要的是可行的,所以这里是:
析构函数可能是 C++ 语言中最可靠的东西。所以如果你想阻止一个被执行,你将不得不自己管理对象的生命周期和内存。
我们可以只 new
Dummy
对象而不 delete
它,但那样会泄漏堆内存,这是不可取的。相反,我们希望在与线程局部对象本身关联的内存中创建但绝不销毁 Dummy
对象。
为此,方法是 std::aligned_storage
和 placement new
:
struct Dummy { ~Dummy() { assert(0); } };
struct DummyWrapper {
DummyWrapper() {
// Create the dummy
dummy_ptr = new (&dummy_data) Dummy();
}
// Intentionally leave the destructor defaulted-out
~DummyWrapper() = default;
operator Dummy&() { return *dummy_ptr; }
std::aligned_storage_t<sizeof(Dummy), alignof(Dummy)> dummy_data;
Dummy* dummy_ptr;
};
__thread DummyWrapper dumb;
DummyWrapper
对象将被构造和销毁,没有解决办法。但是,Dummy
对象只会被创建,不会被销毁,但底层内存管理仍然保持正常。
我特别希望我的一个变量没有构造函数和析构函数。它被定义为这个
struct Dummy { ~Dummy() { assert(0); } };
__thread Dummy dumb;
真正的代码是零初始化,从线程本地内存池中抢内存。该池在 main 的末尾被销毁,因此该析构函数试图访问已释放的内存池。
我可以解决这个问题,但我想以一种干净的方式来解决这个问题。 1) 我可以告诉编译器在所有线程局部(或全局)变量之后释放我的池吗?还是在所有线程局部函数之前对其进行了初始化,以便在适当的时间进行清理?或者更好的是 2) 根本不执行清理?我可以发誓 __thread
不允许 constructors/destructors 所以我很惊讶甚至 运行.
堆栈跟踪显示 __run_exit_handlers
是调用析构函数的函数。它 parents 是 exit
、__libc_start_main
和 start
。这发生在 clang 和 gcc
在我开始回答之前,任何读过这篇文章的人都应该知道这通常是一个非常糟糕的主意,应该作为最后的手段来对待。但是,OP想要的是可行的,所以这里是:
析构函数可能是 C++ 语言中最可靠的东西。所以如果你想阻止一个被执行,你将不得不自己管理对象的生命周期和内存。
我们可以只 new
Dummy
对象而不 delete
它,但那样会泄漏堆内存,这是不可取的。相反,我们希望在与线程局部对象本身关联的内存中创建但绝不销毁 Dummy
对象。
为此,方法是 std::aligned_storage
和 placement new
:
struct Dummy { ~Dummy() { assert(0); } };
struct DummyWrapper {
DummyWrapper() {
// Create the dummy
dummy_ptr = new (&dummy_data) Dummy();
}
// Intentionally leave the destructor defaulted-out
~DummyWrapper() = default;
operator Dummy&() { return *dummy_ptr; }
std::aligned_storage_t<sizeof(Dummy), alignof(Dummy)> dummy_data;
Dummy* dummy_ptr;
};
__thread DummyWrapper dumb;
DummyWrapper
对象将被构造和销毁,没有解决办法。但是,Dummy
对象只会被创建,不会被销毁,但底层内存管理仍然保持正常。