1

Perl 中的线程默认使用自己的本地存储来存储所有变量,以尽量减少线程对现有非线程感知代码的影响。在 Perl 中,可以使用属性创建线程共享变量:

use threads;
use threads::shared;

my $localvar;
my $sharedvar :shared; 

HP-UX 运行时加载程序不支持动态加载包含 (TLS) 线程本地存储的共享库。
因此,当尝试导入包含 TLS 的模块时,会报告以下错误:

“/usr/lib/dld.sl:不能 shl_load() 包含线程本地存储的库”

所以我知道为什么我会收到一个错误我只是不清楚为什么很难用 TLS 加载一个库?

4

1 回答 1

2

TLS 存储的设置方式取决于 TLS 访问模型

在更简单的“初始可执行文件/静态 TLS”模型中,加载程序在运行主可执行文件的第一条指令之前设置 TLS 段。它通过将主可执行文件和它直接依赖的所有共享库的 TLS 要求相加来计算该段的大小。

一旦分配和设置了这个 TLS 段,应用程序就会开始运行,并且可以很好地将指针存储到 TLS 段中。因此,存储段是不可能realloc()的——加载器不知道应用程序中的哪些指针必须更新。

由于您无法重新分配该段,并且其中没有空间用于其他变量;loader 如何处理需要自身 TLS 存储的动态加载库?

glibc 加载器实际上在初始 TLS 中分配了一些额外的空间,因此它可以使用 TLS 动态加载库,只要它们不使用太多空间。一旦这个储备用完,glibc 加载器也将拒绝加载任何具有 TLS 要求的附加库。

在 Solaris 和 Linux 上,可以使用“通用动态 TLS模型”动态加载具有任意 TLS 要求的库。

看起来 HP-UX v1.6 也支持该模型,实际上将其设为默认模型。但是您可能正在运行较旧的操作系统版本,该模型不是默认模型,并且可能根本不受支持。检查您的编译器版本是否支持+tls=dynamic选项,如果支持,使用它进行构建是否有帮助。

于 2009-05-09T21:35:45.817 回答