【发布时间】:2021-12-03 04:22:08
【问题描述】:
我特别希望我的一个变量上没有构造函数和析构函数。是这样定义的
struct Dummy { ~Dummy() { assert(0); } };
__thread Dummy dumb;
真正的代码是零初始化的,并从线程本地内存池中抓取内存。该池在 main 结束时被销毁,因此该析构函数尝试访问已释放的内存池。
我可以解决这个问题,但我想以一种干净的方式来解决这个问题。 1)我可以告诉编译器在所有线程本地(或全局)变量之后释放我的池吗?还是在所有线程本地函数之前对其进行初始化,以便在适当的时间进行清理?或者更好 2) 根本不执行清理?我可以发誓 __thread 不允许构造函数/析构函数,所以我很惊讶这竟然跑了。
堆栈跟踪显示__run_exit_handlers 是调用析构函数的函数。它的父母是exit、__libc_start_main 和start。这发生在 clang 和 gcc 上
【问题讨论】:
-
顺便说一句,你为什么使用
__thread而不是thread_local? C与这有什么关系?这不是 C。 -
这似乎是一个非常奇怪的要求。如果创建变量的线程已经死了,为什么还要让变量保持活动状态?
-
您到底想通过不调用析构函数来防止发生什么?听起来像XY-problem。
-
@EricStotch 我一定是把问题读错了。
thread_local变量将在创建它们的线程死亡时被销毁。 “池在 main 结束时被销毁,因此该析构函数尝试访问已释放的内存池” - 你在实现池或线程时做错了。如果线程从池中获取内存,它们肯定会在死亡时将其返回到池中吗?退出main之前所有线程都加入了吗? -
@EricStotch 我认为正确修复它不会太难,但很难从这些描述中将所有内容拼凑在一起。也许如果您打开一个新问题并在其中输入minimal reproducible example,您将得到一个不需要破解的答案。 :-)