【问题标题】:Why would shl_load() fail for libraries with Thread Local Storage?为什么 shl_load() 对于具有线程本地存储的库会失败?
【发布时间】:2009-04-30 23:27:19
【问题描述】:

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

use threads;
use threads::shared;

my $localvar;
my $sharedvar :shared; 

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

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

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

【问题讨论】:

    标签: perl shared-libraries loadlibrary thread-local


    【解决方案1】:

    TLS 存储的设置方式取决于 TLS 访问 model。

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

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

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2010-10-05
      • 1970-01-01
      • 2011-11-21
      • 2010-09-18
      • 2016-02-11
      • 2010-09-11
      • 2016-06-12
      • 2014-11-29
      • 1970-01-01
      相关资源
      最近更新 更多