2009-04-30 85 views
1

默認情況下,Perl中的線程對所有變量都使用自己的本地存儲,以儘量減少線程對現有非線程感知代碼的影響。在Perl中,線程共享變量可以使用屬性來創建:爲什麼使用Thread Local Storage的庫會失敗shl_load()?

use threads; 
use threads::shared; 

my $localvar; 
my $sharedvar :shared; 

HP-UX運行時加載器不支持包含(TLS)線程本地存儲的共享庫的動態負載。
其結果是,試圖導入包含TLS以下錯誤報道模塊時:

 
"/usr/lib/dld.sl: Can't shl_load() a library containing Thread Local Storage" 

所以我知道爲什麼我收到一個錯誤,我只是不清楚爲什麼這將是難以負荷有TLS的圖書館?

回答

2

設置TLS存儲的方式取決於TLS訪問model

在簡單的「初始可執行文件/靜態TLS」模型中,加載程序在主可執行文件的第一條指令運行之前設置TLS段。它通過添加主要可執行文件及其直接依賴的所有共享庫的TLS要求來計算該段的大小。

一旦這個TLS段被分配和設置,應用程序開始運行,並且可能將指針存儲到TLS段中。因此,對段進行realloc()存儲是不可能的 - 加載程序不知道應用程序中的哪些指針必須更新。

由於您無法重新分配段,並且因爲其中沒有空間用於其他變量;加載器如何處理需要TLS存儲的動態加載庫?

glibc加載程序實際上在初始TLS中分配了一些額外的空間,所以它可以動態加載帶有TLS的庫,只要它們不佔用太多空間。一旦這個儲備用完,glibc加載器也將拒絕加載任何附加TLS要求的庫。

在Solaris和Linux上,可以使用「General Dynamic TLS model」動態加載具有任意TLS要求的庫。

它看起來像HP-UX v1.6也supports那個模型,實際上它是默認的。但是,您可能正在運行一個較舊的操作系統版本,該版本不是默認版本,可能根本不支持。檢查你的編譯器版本是否支持+tls=dynamic選項,如果是的話,是否可以幫助編譯。

相關問題