我正在重组现有的应用程序代码。这种重组的要求之一是我需要存储一个线程特定的变量,该变量经常被引用用于读取和写入。我将有大约 50 个这样的线程。线程特定变量基本上是指向结构的指针。在这里,我无法决定应该如何存储这个变量。我是否应该将其设置为线程特定的键,可以通过pthread_getspecific/pthread_setspecific
? 但是我遇到了一些帖子,这些帖子说对这些的调用非常慢。然后另一种方法可能是拥有一个全局结构,它将所有这些线程特定的指针存储在排序数组(使用二进制搜索)或键值形式的元素哈希表中。键大部分是常量(thread_id),值可以经常更改。同样,这里最好的方法是什么?我知道对所需值的最快访问是实际将此指针传递给每个函数并继续传播它。但这需要我想避免的大量代码重写。提前感谢您的回复。
4 回答
如果您的线程是静态的(也就是说,您启动它们,并且除非程序退出,否则它们不会退出),那么您可以简单地使用您关心的任何映射结构。唯一的技巧是在所有线程被允许运行之前需要填充映射。因此,您可能需要一个互斥锁和条件变量来阻塞所有线程,直到填充映射。之后,你可以广播到所有等待的线程去。由于映射在此之后将永远不会更改,因此每个线程都可以从中读取,而无需任何争用来检索其线程特定信息。
如果您使用的是 GCC,那么您可以使用特定于编译器的扩展。__thread
存储类扩展将全局变量放置在线程特定区域中,以便每个线程都有自己的该全局变量的副本。
__thread struct info_type *info;
如果您使用的是 gcc 工具链(以及其他一些编译器),您还有第三种选择。使用__thread存储类说明符。这是非常有效的。它通过将线程本地存储项隔离到单独的 VM 页面中来工作,这些页面在线程被调度时被切换。这样每个线程都能够指向它自己的变量副本。成本只是每个线程调度一次操作,没有其他方法的每个键查找成本。
不要过早地优化,在你做任何事情之前测量标准方法的性能。它们平均不应使用超过 100 个时钟周期来为您提供线程特定的指针。在许多应用中,这与噪声没有太大区别。
然后,我怀疑您可以通过某种全局变量或函数提供的任何可移植解决方案都比 POSIX 函数更快。基本上,除了您建议的内容之外,它们并没有做太多其他事情,但可能会得到更好的优化。
您拥有的最佳选择是在每个线程的堆栈上实现您的数据,并将指向该数据的指针传递给需要它的函数。
如果您有一个符合 C11 的编译器(我认为 clang 已经实现了该部分),您可以使用_Thread
为您提供所需变量类型的构造。其他编译器(C11 之前)具有此类扩展功能,例如 gcc 系列编译器具有__thread
.
我不明白。该结构是否意味着特定于线程?你的指针指向的那个?如果是,那么具有线程特定结构的问题是什么?如果它是共享的,(同时 50 个线程!)你可以有一个全局变量,尽管同步可能会导致更新值的问题。为什么你想要一个指向所有线程特定数据的指针?