在 C 中,假设我有类似的东西:
struct node {
struct node *next;
void *data;
};
static thread_local struct node *head;
即每个线程一个链表。 如果我想确保在线程终止时释放列表中的所有元素,该怎么做?
C 确实有
tss_create()
允许您创建线程特定的存储 并且 提供析构函数来在线程终止时清理它,但这似乎与声明的对象正交 thread_local
。 似乎没有任何方法可以为 thread_local
对象指定析构函数 - 因此 thread_local
似乎仅对不需要清理的对象有用,例如 int
或类似的对象。
真的吗?
请注意,我只询问关于 C 的问题 — 不是C++。
除上述情况外,请假设我知道 C 是如何工作的。自 20 世纪 80 年代末以来,我一直在用 C 语言编写代码。
线程本地对象是大多数确保可靠对象清理的方法的重要组成部分。 如果 C 在“堆栈展开”期间指定一种特定的对象清理机制作为语言的一部分,则这种机制可能与许多平台可能已经为此目的提供的其他机制不兼容。 如果所有代码都使用相同的线程本地
jmp_buff
对象进行堆栈展开,并遵循以下模式:
jmp_buf *saved_exit,my_exit;
saved_exit = global_exit;
if (setjmp(my_exit))
{
... do necessary cleanup, then ...
global_exit = saved_exit;
longjmp(global_exit, 1)
}
... remainder of function goes here
然后可以根据需要完成“紧急出口”期间所需的任何对象清理。 如果使用一个紧急退出跳板的函数调用一个设置另一个紧急退出跳板的函数,然后该函数调用通过第一个紧急退出跳板退出的代码(绕过第二个跳板),则可能会发生不好的事情,但如果所有代码都使用相同的
jmp_buf
指针,则不会出现问题任何代码都需要关心调用堆栈上较高或较低的代码可能需要哪种类型的清理。