线程在加入之前的本地存储持续时间

huangapple go评论63阅读模式
英文:

thread local storage duration before thread join

问题

Thread local storage (C11的_Thread_local或gcc的__thread)在非分离线程返回后,但在被加入之前(例如通过其他线程的指针访问)仍然可用吗?

英文:

Is thread local storage (C11's _Thread_local or gcc's __thread) still available after (non-detached) thread returns, but before it is joined (eg. accessed through pointer from other thread)?

答案1

得分: 2

gcc__thread情况下,可以从任何线程访问,线程本地存储

> 当对线程本地变量应用地址操作符时,它在运行时进行评估并返回当前线程实例的变量地址。因此获得的地址可以被任何线程使用。当线程终止时,对该线程的线程本地变量的任何指针都变得无效。

在C11中是实现定义的。

§ 6.2.4 对象的存储期(N2176.pdf):

> 其标识符声明为存储类别说明符 _Thread_local 的对象具有线程存储期。它的生命周期是创建它的线程的整个执行期间,其存储的值在线程启动时进行初始化。每个线程都有一个不同的对象,将声明的名称用于表达式中时,它引用与评估表达式的线程相关联的对象。尝试从与对象关联的线程不同的线程间接访问具有线程存储期的对象的结果是实现定义的。

以上内容回答了在拥有线程的情况下是否可以从其他线程访问该线程的线程本地变量。正如两个引用所说,访问它们在线程终止后是无效的。

所以问题变成了一个线程真正何时终止以及在从线程函数返回但在可能已经被“加入”之前,是否可以认为线程是“活动”的问题。

无论是 POSIX 还是 C11 的 thrd_exit 都指出,调用线程在调用 pthread_exit/thrd_exit 或执行 return 时终止。因此,线程本地对象的生命周期在那一点结束,这意味着不再可以访问它们。

英文:

In case of gcc's __thread, it's valid to access from any thread, Thread-Local Storage:

> When the address-of operator is applied to a thread-local variable, it
> is evaluated at run time and returns the address of the current
> thread’s instance of that variable. An address so obtained may be used
> by any thread. When a thread terminates, any pointers to thread-local
> variables in that thread become invalid.

It's implementation defined in C11.

§ 6.2.4 Storage durations of objects (N2176.pdf):

>
> An object whose identifier is declared with the storage-class
> specifier _Thread_local has thread storage duration. Its lifetime is
> the entire execution of the thread for which it is created, and its
> stored value is initialized when the thread is started. There is a
> distinct object per thread, and use of the declared name in an
> expression refers to the object associated with the thread evaluating
> the expression. The result of attempting to indirectly access an
> object with thread storage duration from a thread other than the one
> with which the object is associated is implementation-defined.


The above answers whether accessing thread local variable(s) of a thread from other thread(s) while the owner thread is alive. As both quotes say accessing them after the thread terminates is invalid.

So the question becomes when does a thread really terminate and whether a thread can be considered "alive" after returning from thread function but before it may have been joined.

Both POSIX and C11's thrd_exit say that the calling thread terminates when it calls pthread_exit/thrd_exit or does a return. So the lifetime of the thread local objects end at that point - meaning it's no longer valid to access them.

huangapple
  • 本文由 发表于 2023年5月11日 15:24:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76225056.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定