线程专用数据 vs 线程本地存储

17
我已经阅读了Kerrisk的The Linux Programming Interface: A Linux and UNIX System Programming Handbook,第31章关于线程的内容。该章节包括线程特定数据(31.3.4节)和线程本地存储(31.4节)。这些主题分别在663-669页进行了讲解。
线程特定数据(pthread_key_create、pthread_setspecific、pthread_getspecific等)看起来更加强大,但是使用起来似乎有些繁琐,并且似乎更频繁地使用内存管理器。
线程本地存储(静态和全局声明上的__thread)看起来稍微不那么强大,因为它受到编译时限制,但是使用起来似乎更容易,并且似乎在运行时避免了内存管理器的使用。
我可能对运行时内存管理器有所误解,因为在幕后可能有代码调用pthread_key_create,当它遇到__thread变量时。
Kerrisk没有对这两种策略进行比较/对比,并且他也没有在特定情况下推荐使用哪一种。
为了补充问题的背景:我正在评估一个第三方库。该库使用全局变量,不使用锁,并且我想在多线程程序中使用它。该程序使用线程来最小化网络延迟。
有绝对的赢家吗?还是有不同的情况需要使用其中之一?

1
通常最好两者都不使用。你为什么要使用这个呢? - David Heffernan
谢谢David。这是一个基于网络的多线程程序,旨在帮助在延迟面前维持吞吐量。我想尝试使用第三方库进行解析,但该库使用静态全局变量来保存状态。 - jww
1
嗯,看起来有些凌乱。我知道你的想法。在理想的世界里,信息会通过参数传递。也许考虑一下更加线程友好的库? - David Heffernan
2个回答

15

pthread_key_create 和相关函数比较古老,因此在更多的系统上得到支持。

__thread 相对较新,通常使用起来更加方便,并且(根据维基百科)在大多数仍然重要的 POSIX 系统上得到支持:Solaris Studio C/C++、IBM XL C/C++、GNU C、Clang 以及 Intel C++ 编译器(Linux 系统)。

__thread 还有一个显著的优点,即它可以从信号处理程序中使用(除了使用 dlopened 共享库的 __thread,请参见此 bug),因为其使用不涉及 malloc(具有相同的异常情况)。


请参阅 https://blogs.oracle.com/seongbae/entry/pthread_get_set_specific_vs。`pthread_key_create()` 的一个限制是不能保证调用总是成功的。这使得在没有进行某些假设的情况下,这些调用无法在 __init 类型函数中使用。因此,__thread 是一种简单且保证线程特定数据的方法。 - ReddyVeeru

1

pthread接口是POSIX标准的,因此更具可移植性。如果您打算在Linux系统之外使用代码,请使用它们。另一方面,如果您严格使用gcc / linux,则__thread机制肯定更容易使用。只需注意它是gcc特定的扩展,不支持所有平台。


4
C++11引入了thread_local关键字,类似于__thread,但其支持性应最终得到普及。 - Sebastian Redl
1
__thread 不是 GCC 特有的扩展,它被几乎所有当今重要的 UNIX 编译器所支持。 - Employed Russian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接