告诉编译器不要对我的 __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_mainstart。这发生在 clang 和 gcc

在我开始回答之前,任何读过这篇文章的人都应该知道这通常是一个非常糟糕的主意,应该作为最后的手段来对待。但是,OP想要的是可行的,所以这里是:

析构函数可能是 C++ 语言中最可靠的东西。所以如果你想阻止一个被执行,你将不得不自己管理对象的生命周期和内存。

我们可以只 new Dummy 对象而不 delete 它,但那样会泄漏堆内存,这是不可取的。相反,我们希望在与线程局部对象本身关联的内存中创建但绝不销毁 Dummy 对象。

为此,方法是 std::aligned_storageplacement 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 对象只会被创建,不会被销毁,但底层内存管理仍然保持正常。